LCOV - differential code coverage report
Current view: top level - src/bin/pg_dump - pg_dump.c (source / functions) Coverage Total Hit UNC UBC GBC GNC CBC DUB DCB
Current: a2387c32f2f8a1643c7d71b951587e6bcb2d4744 vs 371a302eecdc82274b0ae2967d18fd726a0aa6a1 Lines: 91.1 % 8376 7628 7 741 67 72 7489 4 14
Current Date: 2025-10-26 12:31:50 -0700 Functions: 98.9 % 188 186 2 2 10 174 1
Baseline: lcov-20251027-010456-baseline Branches: 77.9 % 3934 3065 14 855 37 48 2980
Baseline Date: 2025-10-26 11:01:32 +1300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 80.0 % 15 12 3 12
(30,360] days: 93.5 % 806 754 4 48 1 60 693
(360..) days: 90.8 % 7555 6862 693 66 6796
Function coverage date bins:
(7,30] days: 100.0 % 1 1 1
(30,360] days: 100.0 % 6 6 6
(360..) days: 98.9 % 181 179 2 2 9 168
Branch coverage date bins:
(7,30] days: 90.0 % 10 9 1 9
(30,360] days: 82.2 % 583 479 13 91 2 39 438
(360..) days: 77.1 % 3341 2577 764 35 2542

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * pg_dump.c
                                  4                 :                :  *    pg_dump is a utility for dumping out a postgres database
                                  5                 :                :  *    into a script file.
                                  6                 :                :  *
                                  7                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  *  pg_dump will read the system catalogs in a database and dump out a
                                 11                 :                :  *  script that reproduces the schema in terms of SQL that is understood
                                 12                 :                :  *  by PostgreSQL
                                 13                 :                :  *
                                 14                 :                :  *  Note that pg_dump runs in a transaction-snapshot mode transaction,
                                 15                 :                :  *  so it sees a consistent snapshot of the database including system
                                 16                 :                :  *  catalogs. However, it relies in part on various specialized backend
                                 17                 :                :  *  functions like pg_get_indexdef(), and those things tend to look at
                                 18                 :                :  *  the currently committed state.  So it is possible to get 'cache
                                 19                 :                :  *  lookup failed' error if someone performs DDL changes while a dump is
                                 20                 :                :  *  happening. The window for this sort of thing is from the acquisition
                                 21                 :                :  *  of the transaction snapshot to getSchemaData() (when pg_dump acquires
                                 22                 :                :  *  AccessShareLock on every table it intends to dump). It isn't very large,
                                 23                 :                :  *  but it can happen.
                                 24                 :                :  *
                                 25                 :                :  *  http://archives.postgresql.org/pgsql-bugs/2010-02/msg00187.php
                                 26                 :                :  *
                                 27                 :                :  * IDENTIFICATION
                                 28                 :                :  *    src/bin/pg_dump/pg_dump.c
                                 29                 :                :  *
                                 30                 :                :  *-------------------------------------------------------------------------
                                 31                 :                :  */
                                 32                 :                : #include "postgres_fe.h"
                                 33                 :                : 
                                 34                 :                : #include <unistd.h>
                                 35                 :                : #include <ctype.h>
                                 36                 :                : #include <limits.h>
                                 37                 :                : #ifdef HAVE_TERMIOS_H
                                 38                 :                : #include <termios.h>
                                 39                 :                : #endif
                                 40                 :                : 
                                 41                 :                : #include "access/attnum.h"
                                 42                 :                : #include "access/sysattr.h"
                                 43                 :                : #include "access/transam.h"
                                 44                 :                : #include "catalog/pg_aggregate_d.h"
                                 45                 :                : #include "catalog/pg_am_d.h"
                                 46                 :                : #include "catalog/pg_attribute_d.h"
                                 47                 :                : #include "catalog/pg_authid_d.h"
                                 48                 :                : #include "catalog/pg_cast_d.h"
                                 49                 :                : #include "catalog/pg_class_d.h"
                                 50                 :                : #include "catalog/pg_constraint_d.h"
                                 51                 :                : #include "catalog/pg_default_acl_d.h"
                                 52                 :                : #include "catalog/pg_largeobject_d.h"
                                 53                 :                : #include "catalog/pg_largeobject_metadata_d.h"
                                 54                 :                : #include "catalog/pg_proc_d.h"
                                 55                 :                : #include "catalog/pg_publication_d.h"
                                 56                 :                : #include "catalog/pg_shdepend_d.h"
                                 57                 :                : #include "catalog/pg_subscription_d.h"
                                 58                 :                : #include "catalog/pg_type_d.h"
                                 59                 :                : #include "common/connect.h"
                                 60                 :                : #include "common/int.h"
                                 61                 :                : #include "common/relpath.h"
                                 62                 :                : #include "common/shortest_dec.h"
                                 63                 :                : #include "compress_io.h"
                                 64                 :                : #include "dumputils.h"
                                 65                 :                : #include "fe_utils/option_utils.h"
                                 66                 :                : #include "fe_utils/string_utils.h"
                                 67                 :                : #include "filter.h"
                                 68                 :                : #include "getopt_long.h"
                                 69                 :                : #include "libpq/libpq-fs.h"
                                 70                 :                : #include "parallel.h"
                                 71                 :                : #include "pg_backup_db.h"
                                 72                 :                : #include "pg_backup_utils.h"
                                 73                 :                : #include "pg_dump.h"
                                 74                 :                : #include "storage/block.h"
                                 75                 :                : 
                                 76                 :                : typedef struct
                                 77                 :                : {
                                 78                 :                :     Oid         roleoid;        /* role's OID */
                                 79                 :                :     const char *rolename;       /* role's name */
                                 80                 :                : } RoleNameItem;
                                 81                 :                : 
                                 82                 :                : typedef struct
                                 83                 :                : {
                                 84                 :                :     const char *descr;          /* comment for an object */
                                 85                 :                :     Oid         classoid;       /* object class (catalog OID) */
                                 86                 :                :     Oid         objoid;         /* object OID */
                                 87                 :                :     int         objsubid;       /* subobject (table column #) */
                                 88                 :                : } CommentItem;
                                 89                 :                : 
                                 90                 :                : typedef struct
                                 91                 :                : {
                                 92                 :                :     const char *provider;       /* label provider of this security label */
                                 93                 :                :     const char *label;          /* security label for an object */
                                 94                 :                :     Oid         classoid;       /* object class (catalog OID) */
                                 95                 :                :     Oid         objoid;         /* object OID */
                                 96                 :                :     int         objsubid;       /* subobject (table column #) */
                                 97                 :                : } SecLabelItem;
                                 98                 :                : 
                                 99                 :                : typedef struct
                                100                 :                : {
                                101                 :                :     Oid         oid;            /* object OID */
                                102                 :                :     char        relkind;        /* object kind */
                                103                 :                :     RelFileNumber relfilenumber;    /* object filenode */
                                104                 :                :     Oid         toast_oid;      /* toast table OID */
                                105                 :                :     RelFileNumber toast_relfilenumber;  /* toast table filenode */
                                106                 :                :     Oid         toast_index_oid;    /* toast table index OID */
                                107                 :                :     RelFileNumber toast_index_relfilenumber;    /* toast table index filenode */
                                108                 :                : } BinaryUpgradeClassOidItem;
                                109                 :                : 
                                110                 :                : /* sequence types */
                                111                 :                : typedef enum SeqType
                                112                 :                : {
                                113                 :                :     SEQTYPE_SMALLINT,
                                114                 :                :     SEQTYPE_INTEGER,
                                115                 :                :     SEQTYPE_BIGINT,
                                116                 :                : } SeqType;
                                117                 :                : 
                                118                 :                : static const char *const SeqTypeNames[] =
                                119                 :                : {
                                120                 :                :     [SEQTYPE_SMALLINT] = "smallint",
                                121                 :                :     [SEQTYPE_INTEGER] = "integer",
                                122                 :                :     [SEQTYPE_BIGINT] = "bigint",
                                123                 :                : };
                                124                 :                : 
                                125                 :                : StaticAssertDecl(lengthof(SeqTypeNames) == (SEQTYPE_BIGINT + 1),
                                126                 :                :                  "array length mismatch");
                                127                 :                : 
                                128                 :                : typedef struct
                                129                 :                : {
                                130                 :                :     Oid         oid;            /* sequence OID */
                                131                 :                :     SeqType     seqtype;        /* data type of sequence */
                                132                 :                :     bool        cycled;         /* whether sequence cycles */
                                133                 :                :     int64       minv;           /* minimum value */
                                134                 :                :     int64       maxv;           /* maximum value */
                                135                 :                :     int64       startv;         /* start value */
                                136                 :                :     int64       incby;          /* increment value */
                                137                 :                :     int64       cache;          /* cache size */
                                138                 :                :     int64       last_value;     /* last value of sequence */
                                139                 :                :     bool        is_called;      /* whether nextval advances before returning */
                                140                 :                : } SequenceItem;
                                141                 :                : 
                                142                 :                : typedef enum OidOptions
                                143                 :                : {
                                144                 :                :     zeroIsError = 1,
                                145                 :                :     zeroAsStar = 2,
                                146                 :                :     zeroAsNone = 4,
                                147                 :                : } OidOptions;
                                148                 :                : 
                                149                 :                : /* global decls */
                                150                 :                : static bool dosync = true;      /* Issue fsync() to make dump durable on disk. */
                                151                 :                : 
                                152                 :                : static Oid  g_last_builtin_oid; /* value of the last builtin oid */
                                153                 :                : 
                                154                 :                : /* The specified names/patterns should to match at least one entity */
                                155                 :                : static int  strict_names = 0;
                                156                 :                : 
                                157                 :                : static pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE;
                                158                 :                : 
                                159                 :                : /*
                                160                 :                :  * Object inclusion/exclusion lists
                                161                 :                :  *
                                162                 :                :  * The string lists record the patterns given by command-line switches,
                                163                 :                :  * which we then convert to lists of OIDs of matching objects.
                                164                 :                :  */
                                165                 :                : static SimpleStringList schema_include_patterns = {NULL, NULL};
                                166                 :                : static SimpleOidList schema_include_oids = {NULL, NULL};
                                167                 :                : static SimpleStringList schema_exclude_patterns = {NULL, NULL};
                                168                 :                : static SimpleOidList schema_exclude_oids = {NULL, NULL};
                                169                 :                : 
                                170                 :                : static SimpleStringList table_include_patterns = {NULL, NULL};
                                171                 :                : static SimpleStringList table_include_patterns_and_children = {NULL, NULL};
                                172                 :                : static SimpleOidList table_include_oids = {NULL, NULL};
                                173                 :                : static SimpleStringList table_exclude_patterns = {NULL, NULL};
                                174                 :                : static SimpleStringList table_exclude_patterns_and_children = {NULL, NULL};
                                175                 :                : static SimpleOidList table_exclude_oids = {NULL, NULL};
                                176                 :                : static SimpleStringList tabledata_exclude_patterns = {NULL, NULL};
                                177                 :                : static SimpleStringList tabledata_exclude_patterns_and_children = {NULL, NULL};
                                178                 :                : static SimpleOidList tabledata_exclude_oids = {NULL, NULL};
                                179                 :                : 
                                180                 :                : static SimpleStringList foreign_servers_include_patterns = {NULL, NULL};
                                181                 :                : static SimpleOidList foreign_servers_include_oids = {NULL, NULL};
                                182                 :                : 
                                183                 :                : static SimpleStringList extension_include_patterns = {NULL, NULL};
                                184                 :                : static SimpleOidList extension_include_oids = {NULL, NULL};
                                185                 :                : 
                                186                 :                : static SimpleStringList extension_exclude_patterns = {NULL, NULL};
                                187                 :                : static SimpleOidList extension_exclude_oids = {NULL, NULL};
                                188                 :                : 
                                189                 :                : static const CatalogId nilCatalogId = {0, 0};
                                190                 :                : 
                                191                 :                : /* override for standard extra_float_digits setting */
                                192                 :                : static bool have_extra_float_digits = false;
                                193                 :                : static int  extra_float_digits;
                                194                 :                : 
                                195                 :                : /* sorted table of role names */
                                196                 :                : static RoleNameItem *rolenames = NULL;
                                197                 :                : static int  nrolenames = 0;
                                198                 :                : 
                                199                 :                : /* sorted table of comments */
                                200                 :                : static CommentItem *comments = NULL;
                                201                 :                : static int  ncomments = 0;
                                202                 :                : 
                                203                 :                : /* sorted table of security labels */
                                204                 :                : static SecLabelItem *seclabels = NULL;
                                205                 :                : static int  nseclabels = 0;
                                206                 :                : 
                                207                 :                : /* sorted table of pg_class information for binary upgrade */
                                208                 :                : static BinaryUpgradeClassOidItem *binaryUpgradeClassOids = NULL;
                                209                 :                : static int  nbinaryUpgradeClassOids = 0;
                                210                 :                : 
                                211                 :                : /* sorted table of sequences */
                                212                 :                : static SequenceItem *sequences = NULL;
                                213                 :                : static int  nsequences = 0;
                                214                 :                : 
                                215                 :                : /*
                                216                 :                :  * For binary upgrade, the dump ID of pg_largeobject_metadata is saved for use
                                217                 :                :  * as a dependency for pg_shdepend and any large object comments/seclabels.
                                218                 :                :  */
                                219                 :                : static DumpId lo_metadata_dumpId;
                                220                 :                : 
                                221                 :                : /* Maximum number of relations to fetch in a fetchAttributeStats() call. */
                                222                 :                : #define MAX_ATTR_STATS_RELS 64
                                223                 :                : 
                                224                 :                : /*
                                225                 :                :  * The default number of rows per INSERT when
                                226                 :                :  * --inserts is specified without --rows-per-insert
                                227                 :                :  */
                                228                 :                : #define DUMP_DEFAULT_ROWS_PER_INSERT 1
                                229                 :                : 
                                230                 :                : /*
                                231                 :                :  * Maximum number of large objects to group into a single ArchiveEntry.
                                232                 :                :  * At some point we might want to make this user-controllable, but for now
                                233                 :                :  * a hard-wired setting will suffice.
                                234                 :                :  */
                                235                 :                : #define MAX_BLOBS_PER_ARCHIVE_ENTRY 1000
                                236                 :                : 
                                237                 :                : /*
                                238                 :                :  * Macro for producing quoted, schema-qualified name of a dumpable object.
                                239                 :                :  */
                                240                 :                : #define fmtQualifiedDumpable(obj) \
                                241                 :                :     fmtQualifiedId((obj)->dobj.namespace->dobj.name, \
                                242                 :                :                    (obj)->dobj.name)
                                243                 :                : 
                                244                 :                : static void help(const char *progname);
                                245                 :                : static void setup_connection(Archive *AH,
                                246                 :                :                              const char *dumpencoding, const char *dumpsnapshot,
                                247                 :                :                              char *use_role);
                                248                 :                : static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
                                249                 :                : static void expand_schema_name_patterns(Archive *fout,
                                250                 :                :                                         SimpleStringList *patterns,
                                251                 :                :                                         SimpleOidList *oids,
                                252                 :                :                                         bool strict_names);
                                253                 :                : static void expand_extension_name_patterns(Archive *fout,
                                254                 :                :                                            SimpleStringList *patterns,
                                255                 :                :                                            SimpleOidList *oids,
                                256                 :                :                                            bool strict_names);
                                257                 :                : static void expand_foreign_server_name_patterns(Archive *fout,
                                258                 :                :                                                 SimpleStringList *patterns,
                                259                 :                :                                                 SimpleOidList *oids);
                                260                 :                : static void expand_table_name_patterns(Archive *fout,
                                261                 :                :                                        SimpleStringList *patterns,
                                262                 :                :                                        SimpleOidList *oids,
                                263                 :                :                                        bool strict_names,
                                264                 :                :                                        bool with_child_tables);
                                265                 :                : static void prohibit_crossdb_refs(PGconn *conn, const char *dbname,
                                266                 :                :                                   const char *pattern);
                                267                 :                : 
                                268                 :                : static NamespaceInfo *findNamespace(Oid nsoid);
                                269                 :                : static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo);
                                270                 :                : static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo);
                                271                 :                : static const char *getRoleName(const char *roleoid_str);
                                272                 :                : static void collectRoleNames(Archive *fout);
                                273                 :                : static void getAdditionalACLs(Archive *fout);
                                274                 :                : static void dumpCommentExtended(Archive *fout, const char *type,
                                275                 :                :                                 const char *name, const char *namespace,
                                276                 :                :                                 const char *owner, CatalogId catalogId,
                                277                 :                :                                 int subid, DumpId dumpId,
                                278                 :                :                                 const char *initdb_comment);
                                279                 :                : static inline void dumpComment(Archive *fout, const char *type,
                                280                 :                :                                const char *name, const char *namespace,
                                281                 :                :                                const char *owner, CatalogId catalogId,
                                282                 :                :                                int subid, DumpId dumpId);
                                283                 :                : static int  findComments(Oid classoid, Oid objoid, CommentItem **items);
                                284                 :                : static void collectComments(Archive *fout);
                                285                 :                : static void dumpSecLabel(Archive *fout, const char *type, const char *name,
                                286                 :                :                          const char *namespace, const char *owner,
                                287                 :                :                          CatalogId catalogId, int subid, DumpId dumpId);
                                288                 :                : static int  findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items);
                                289                 :                : static void collectSecLabels(Archive *fout);
                                290                 :                : static void dumpDumpableObject(Archive *fout, DumpableObject *dobj);
                                291                 :                : static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo);
                                292                 :                : static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo);
                                293                 :                : static void dumpType(Archive *fout, const TypeInfo *tyinfo);
                                294                 :                : static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo);
                                295                 :                : static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo);
                                296                 :                : static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo);
                                297                 :                : static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo);
                                298                 :                : static void dumpDomain(Archive *fout, const TypeInfo *tyinfo);
                                299                 :                : static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo);
                                300                 :                : static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
                                301                 :                :                                          PGresult *res);
                                302                 :                : static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo);
                                303                 :                : static void dumpProcLang(Archive *fout, const ProcLangInfo *plang);
                                304                 :                : static void dumpFunc(Archive *fout, const FuncInfo *finfo);
                                305                 :                : static void dumpCast(Archive *fout, const CastInfo *cast);
                                306                 :                : static void dumpTransform(Archive *fout, const TransformInfo *transform);
                                307                 :                : static void dumpOpr(Archive *fout, const OprInfo *oprinfo);
                                308                 :                : static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo);
                                309                 :                : static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo);
                                310                 :                : static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo);
                                311                 :                : static void dumpCollation(Archive *fout, const CollInfo *collinfo);
                                312                 :                : static void dumpConversion(Archive *fout, const ConvInfo *convinfo);
                                313                 :                : static void dumpRule(Archive *fout, const RuleInfo *rinfo);
                                314                 :                : static void dumpAgg(Archive *fout, const AggInfo *agginfo);
                                315                 :                : static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo);
                                316                 :                : static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo);
                                317                 :                : static void dumpTable(Archive *fout, const TableInfo *tbinfo);
                                318                 :                : static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo);
                                319                 :                : static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo);
                                320                 :                : static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo);
                                321                 :                : static void collectSequences(Archive *fout);
                                322                 :                : static void dumpSequence(Archive *fout, const TableInfo *tbinfo);
                                323                 :                : static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo);
                                324                 :                : static void dumpIndex(Archive *fout, const IndxInfo *indxinfo);
                                325                 :                : static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo);
                                326                 :                : static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo);
                                327                 :                : static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo);
                                328                 :                : static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo);
                                329                 :                : static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo);
                                330                 :                : static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo);
                                331                 :                : static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo);
                                332                 :                : static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo);
                                333                 :                : static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo);
                                334                 :                : static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo);
                                335                 :                : static void dumpUserMappings(Archive *fout,
                                336                 :                :                              const char *servername, const char *namespace,
                                337                 :                :                              const char *owner, CatalogId catalogId, DumpId dumpId);
                                338                 :                : static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo);
                                339                 :                : 
                                340                 :                : static DumpId dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
                                341                 :                :                       const char *type, const char *name, const char *subname,
                                342                 :                :                       const char *nspname, const char *tag, const char *owner,
                                343                 :                :                       const DumpableAcl *dacl);
                                344                 :                : 
                                345                 :                : static void getDependencies(Archive *fout);
                                346                 :                : static void BuildArchiveDependencies(Archive *fout);
                                347                 :                : static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
                                348                 :                :                                      DumpId **dependencies, int *nDeps, int *allocDeps);
                                349                 :                : 
                                350                 :                : static DumpableObject *createBoundaryObjects(void);
                                351                 :                : static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
                                352                 :                :                                     DumpableObject *boundaryObjs);
                                353                 :                : 
                                354                 :                : static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx);
                                355                 :                : static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
                                356                 :                : static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind);
                                357                 :                : static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo);
                                358                 :                : static void buildMatViewRefreshDependencies(Archive *fout);
                                359                 :                : static void getTableDataFKConstraints(void);
                                360                 :                : static void determineNotNullFlags(Archive *fout, PGresult *res, int r,
                                361                 :                :                                   TableInfo *tbinfo, int j,
                                362                 :                :                                   int i_notnull_name,
                                363                 :                :                                   int i_notnull_comment,
                                364                 :                :                                   int i_notnull_invalidoid,
                                365                 :                :                                   int i_notnull_noinherit,
                                366                 :                :                                   int i_notnull_islocal,
                                367                 :                :                                   PQExpBuffer *invalidnotnulloids);
                                368                 :                : static char *format_function_arguments(const FuncInfo *finfo, const char *funcargs,
                                369                 :                :                                        bool is_agg);
                                370                 :                : static char *format_function_signature(Archive *fout,
                                371                 :                :                                        const FuncInfo *finfo, bool honor_quotes);
                                372                 :                : static char *convertRegProcReference(const char *proc);
                                373                 :                : static char *getFormattedOperatorName(const char *oproid);
                                374                 :                : static char *convertTSFunction(Archive *fout, Oid funcOid);
                                375                 :                : static const char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
                                376                 :                : static void getLOs(Archive *fout);
                                377                 :                : static void dumpLO(Archive *fout, const LoInfo *loinfo);
                                378                 :                : static int  dumpLOs(Archive *fout, const void *arg);
                                379                 :                : static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo);
                                380                 :                : static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo);
                                381                 :                : static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo);
                                382                 :                : static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo);
                                383                 :                : static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo);
                                384                 :                : static void dumpDatabase(Archive *fout);
                                385                 :                : static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                                386                 :                :                                const char *dbname, Oid dboid);
                                387                 :                : static void dumpEncoding(Archive *AH);
                                388                 :                : static void dumpStdStrings(Archive *AH);
                                389                 :                : static void dumpSearchPath(Archive *AH);
                                390                 :                : static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                                391                 :                :                                                      PQExpBuffer upgrade_buffer,
                                392                 :                :                                                      Oid pg_type_oid,
                                393                 :                :                                                      bool force_array_type,
                                394                 :                :                                                      bool include_multirange_type);
                                395                 :                : static void binary_upgrade_set_type_oids_by_rel(Archive *fout,
                                396                 :                :                                                 PQExpBuffer upgrade_buffer,
                                397                 :                :                                                 const TableInfo *tbinfo);
                                398                 :                : static void collectBinaryUpgradeClassOids(Archive *fout);
                                399                 :                : static void binary_upgrade_set_pg_class_oids(Archive *fout,
                                400                 :                :                                              PQExpBuffer upgrade_buffer,
                                401                 :                :                                              Oid pg_class_oid);
                                402                 :                : static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                                403                 :                :                                             const DumpableObject *dobj,
                                404                 :                :                                             const char *objtype,
                                405                 :                :                                             const char *objname,
                                406                 :                :                                             const char *objnamespace);
                                407                 :                : static const char *getAttrName(int attrnum, const TableInfo *tblInfo);
                                408                 :                : static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
                                409                 :                : static bool nonemptyReloptions(const char *reloptions);
                                410                 :                : static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
                                411                 :                :                                     const char *prefix, Archive *fout);
                                412                 :                : static char *get_synchronized_snapshot(Archive *fout);
                                413                 :                : static void set_restrict_relation_kind(Archive *AH, const char *value);
                                414                 :                : static void setupDumpWorker(Archive *AH);
                                415                 :                : static TableInfo *getRootTableInfo(const TableInfo *tbinfo);
                                416                 :                : static bool forcePartitionRootLoad(const TableInfo *tbinfo);
                                417                 :                : static void read_dump_filters(const char *filename, DumpOptions *dopt);
                                418                 :                : 
                                419                 :                : 
                                420                 :                : int
 8571 tgl@sss.pgh.pa.us         421                 :CBC         297 : main(int argc, char **argv)
                                422                 :                : {
                                423                 :                :     int         c;
                                424                 :            297 :     const char *filename = NULL;
                                425                 :            297 :     const char *format = "p";
                                426                 :                :     TableInfo  *tblinfo;
                                427                 :                :     int         numTables;
                                428                 :                :     DumpableObject **dobjs;
                                429                 :                :     int         numObjs;
                                430                 :                :     DumpableObject *boundaryObjs;
                                431                 :                :     int         i;
                                432                 :                :     int         optindex;
                                433                 :                :     RestoreOptions *ropt;
                                434                 :                :     Archive    *fout;           /* the script file */
 2401 peter@eisentraut.org      435                 :            297 :     bool        g_verbose = false;
 4031 alvherre@alvh.no-ip.      436                 :            297 :     const char *dumpencoding = NULL;
 3997 simon@2ndQuadrant.co      437                 :            297 :     const char *dumpsnapshot = NULL;
 4031 alvherre@alvh.no-ip.      438                 :            297 :     char       *use_role = NULL;
 4600 andrew@dunslane.net       439                 :            297 :     int         numWorkers = 1;
 8571 tgl@sss.pgh.pa.us         440                 :            297 :     int         plainText = 0;
 5391 heikki.linnakangas@i      441                 :            297 :     ArchiveFormat archiveFormat = archUnknown;
                                442                 :                :     ArchiveMode archiveMode;
 1060 michael@paquier.xyz       443                 :            297 :     pg_compress_specification compression_spec = {0};
                                444                 :            297 :     char       *compression_detail = NULL;
                                445                 :            297 :     char       *compression_algorithm_str = "none";
                                446                 :            297 :     char       *error_detail = NULL;
                                447                 :            297 :     bool        user_compression_defined = false;
  782 nathan@postgresql.or      448                 :            297 :     DataDirSyncMethod sync_method = DATA_DIR_SYNC_METHOD_FSYNC;
  336                           449                 :            297 :     bool        data_only = false;
                                450                 :            297 :     bool        schema_only = false;
  249 jdavis@postgresql.or      451                 :            297 :     bool        statistics_only = false;
  216                           452                 :            297 :     bool        with_statistics = false;
  249                           453                 :            297 :     bool        no_data = false;
                                454                 :            297 :     bool        no_schema = false;
                                455                 :            297 :     bool        no_statistics = false;
                                456                 :                : 
                                457                 :                :     static DumpOptions dopt;
                                458                 :                : 
                                459                 :                :     static struct option long_options[] = {
                                460                 :                :         {"data-only", no_argument, NULL, 'a'},
                                461                 :                :         {"blobs", no_argument, NULL, 'b'},
                                462                 :                :         {"large-objects", no_argument, NULL, 'b'},
                                463                 :                :         {"no-blobs", no_argument, NULL, 'B'},
                                464                 :                :         {"no-large-objects", no_argument, NULL, 'B'},
                                465                 :                :         {"clean", no_argument, NULL, 'c'},
                                466                 :                :         {"create", no_argument, NULL, 'C'},
                                467                 :                :         {"dbname", required_argument, NULL, 'd'},
                                468                 :                :         {"extension", required_argument, NULL, 'e'},
                                469                 :                :         {"file", required_argument, NULL, 'f'},
                                470                 :                :         {"format", required_argument, NULL, 'F'},
                                471                 :                :         {"host", required_argument, NULL, 'h'},
                                472                 :                :         {"jobs", 1, NULL, 'j'},
                                473                 :                :         {"no-reconnect", no_argument, NULL, 'R'},
                                474                 :                :         {"no-owner", no_argument, NULL, 'O'},
                                475                 :                :         {"port", required_argument, NULL, 'p'},
                                476                 :                :         {"schema", required_argument, NULL, 'n'},
                                477                 :                :         {"exclude-schema", required_argument, NULL, 'N'},
                                478                 :                :         {"schema-only", no_argument, NULL, 's'},
                                479                 :                :         {"superuser", required_argument, NULL, 'S'},
                                480                 :                :         {"table", required_argument, NULL, 't'},
                                481                 :                :         {"exclude-table", required_argument, NULL, 'T'},
                                482                 :                :         {"no-password", no_argument, NULL, 'w'},
                                483                 :                :         {"password", no_argument, NULL, 'W'},
                                484                 :                :         {"username", required_argument, NULL, 'U'},
                                485                 :                :         {"verbose", no_argument, NULL, 'v'},
                                486                 :                :         {"no-privileges", no_argument, NULL, 'x'},
                                487                 :                :         {"no-acl", no_argument, NULL, 'x'},
                                488                 :                :         {"compress", required_argument, NULL, 'Z'},
                                489                 :                :         {"encoding", required_argument, NULL, 'E'},
                                490                 :                :         {"help", no_argument, NULL, '?'},
                                491                 :                :         {"version", no_argument, NULL, 'V'},
                                492                 :                : 
                                493                 :                :         /*
                                494                 :                :          * the following options don't have an equivalent short option letter
                                495                 :                :          */
                                496                 :                :         {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
                                497                 :                :         {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
                                498                 :                :         {"column-inserts", no_argument, &dopt.column_inserts, 1},
                                499                 :                :         {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
                                500                 :                :         {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
                                501                 :                :         {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
                                502                 :                :         {"exclude-table-data", required_argument, NULL, 4},
                                503                 :                :         {"extra-float-digits", required_argument, NULL, 8},
                                504                 :                :         {"if-exists", no_argument, &dopt.if_exists, 1},
                                505                 :                :         {"inserts", no_argument, NULL, 9},
                                506                 :                :         {"lock-wait-timeout", required_argument, NULL, 2},
                                507                 :                :         {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
                                508                 :                :         {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
                                509                 :                :         {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
                                510                 :                :         {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
                                511                 :                :         {"role", required_argument, NULL, 3},
                                512                 :                :         {"section", required_argument, NULL, 5},
                                513                 :                :         {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
                                514                 :                :         {"snapshot", required_argument, NULL, 6},
                                515                 :                :         {"statistics", no_argument, NULL, 22},
                                516                 :                :         {"statistics-only", no_argument, NULL, 18},
                                517                 :                :         {"strict-names", no_argument, &strict_names, 1},
                                518                 :                :         {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
                                519                 :                :         {"no-comments", no_argument, &dopt.no_comments, 1},
                                520                 :                :         {"no-data", no_argument, NULL, 19},
                                521                 :                :         {"no-policies", no_argument, &dopt.no_policies, 1},
                                522                 :                :         {"no-publications", no_argument, &dopt.no_publications, 1},
                                523                 :                :         {"no-schema", no_argument, NULL, 20},
                                524                 :                :         {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
                                525                 :                :         {"no-statistics", no_argument, NULL, 21},
                                526                 :                :         {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
                                527                 :                :         {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
                                528                 :                :         {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
                                529                 :                :         {"no-sync", no_argument, NULL, 7},
                                530                 :                :         {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
                                531                 :                :         {"rows-per-insert", required_argument, NULL, 10},
                                532                 :                :         {"include-foreign-data", required_argument, NULL, 11},
                                533                 :                :         {"table-and-children", required_argument, NULL, 12},
                                534                 :                :         {"exclude-table-and-children", required_argument, NULL, 13},
                                535                 :                :         {"exclude-table-data-and-children", required_argument, NULL, 14},
                                536                 :                :         {"sync-method", required_argument, NULL, 15},
                                537                 :                :         {"filter", required_argument, NULL, 16},
                                538                 :                :         {"exclude-extension", required_argument, NULL, 17},
                                539                 :                :         {"sequence-data", no_argument, &dopt.sequence_data, 1},
                                540                 :                :         {"restrict-key", required_argument, NULL, 25},
                                541                 :                : 
                                542                 :                :         {NULL, 0, NULL, 0}
                                543                 :                :     };
                                544                 :                : 
 2401 peter@eisentraut.org      545                 :            297 :     pg_logging_init(argv[0]);
                                546                 :            297 :     pg_logging_set_level(PG_LOG_WARNING);
 6164 peter_e@gmx.net           547                 :            297 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
                                548                 :                : 
                                549                 :                :     /*
                                550                 :                :      * Initialize what we need for parallel execution, especially for thread
                                551                 :                :      * support on Windows.
                                552                 :                :      */
 4600 andrew@dunslane.net       553                 :            297 :     init_parallel_dump_utils();
                                554                 :                : 
 8242 bruce@momjian.us          555                 :            297 :     progname = get_progname(argv[0]);
                                556                 :                : 
 8571 tgl@sss.pgh.pa.us         557         [ +  - ]:            297 :     if (argc > 1)
                                558                 :                :     {
                                559   [ +  +  -  + ]:            297 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                                560                 :                :         {
                                561                 :              1 :             help(progname);
 5002 rhaas@postgresql.org      562                 :              1 :             exit_nicely(0);
                                563                 :                :         }
 8571 tgl@sss.pgh.pa.us         564   [ +  +  +  + ]:            296 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                                565                 :                :         {
                                566                 :             62 :             puts("pg_dump (PostgreSQL) " PG_VERSION);
 5002 rhaas@postgresql.org      567                 :             62 :             exit_nicely(0);
                                568                 :                :         }
                                569                 :                :     }
                                570                 :                : 
 3942 tgl@sss.pgh.pa.us         571                 :            234 :     InitDumpOptions(&dopt);
                                572                 :                : 
  249 jdavis@postgresql.or      573                 :           1306 :     while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxXZ:",
 8330 peter_e@gmx.net           574         [ +  + ]:           1306 :                             long_options, &optindex)) != -1)
                                575                 :                :     {
 8571 tgl@sss.pgh.pa.us         576   [ +  +  +  +  :           1080 :         switch (c)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     -  +  +  +  +  
                                     +  +  +  -  +  
                                     +  +  +  +  +  
                                     +  +  -  +  +  
                                     +  +  +  +  +  
                                              +  + ]
                                577                 :                :         {
                                578                 :              9 :             case 'a':           /* Dump data only */
  336 nathan@postgresql.or      579                 :              9 :                 data_only = true;
 8571 tgl@sss.pgh.pa.us         580                 :              9 :                 break;
                                581                 :                : 
 1057 peter@eisentraut.org      582                 :              1 :             case 'b':           /* Dump LOs */
                                583                 :              1 :                 dopt.outputLOs = true;
 8571 tgl@sss.pgh.pa.us         584                 :              1 :                 break;
                                585                 :                : 
 1057 peter@eisentraut.org      586                 :              2 :             case 'B':           /* Don't dump LOs */
                                587                 :              2 :                 dopt.dontOutputLOs = true;
 3254 sfrost@snowman.net        588                 :              2 :                 break;
                                589                 :                : 
 7317 bruce@momjian.us          590                 :              6 :             case 'c':           /* clean (i.e., drop) schema prior to create */
 3942 tgl@sss.pgh.pa.us         591                 :              6 :                 dopt.outputClean = 1;
 8571                           592                 :              6 :                 break;
                                593                 :                : 
                                594                 :             29 :             case 'C':           /* Create DB */
 3942                           595                 :             29 :                 dopt.outputCreateDB = 1;
 8571                           596                 :             29 :                 break;
                                597                 :                : 
 4627 heikki.linnakangas@i      598                 :              5 :             case 'd':           /* database name */
 1859 tgl@sss.pgh.pa.us         599                 :              5 :                 dopt.cparams.dbname = pg_strdup(optarg);
 4627 heikki.linnakangas@i      600                 :              5 :                 break;
                                601                 :                : 
 1671 michael@paquier.xyz       602                 :              4 :             case 'e':           /* include extension(s) */
                                603                 :              4 :                 simple_string_list_append(&extension_include_patterns, optarg);
                                604                 :              4 :                 dopt.include_everything = false;
                                605                 :              4 :                 break;
                                606                 :                : 
 7414 bruce@momjian.us          607                 :              2 :             case 'E':           /* Dump encoding */
 4763                           608                 :              2 :                 dumpencoding = pg_strdup(optarg);
 7414                           609                 :              2 :                 break;
                                610                 :                : 
 8571 tgl@sss.pgh.pa.us         611                 :            187 :             case 'f':
 4763 bruce@momjian.us          612                 :            187 :                 filename = pg_strdup(optarg);
 8571 tgl@sss.pgh.pa.us         613                 :            187 :                 break;
                                614                 :                : 
                                615                 :            114 :             case 'F':
 4763 bruce@momjian.us          616                 :            114 :                 format = pg_strdup(optarg);
 8571 tgl@sss.pgh.pa.us         617                 :            114 :                 break;
                                618                 :                : 
                                619                 :             34 :             case 'h':           /* server host */
 1859                           620                 :             34 :                 dopt.cparams.pghost = pg_strdup(optarg);
 8571                           621                 :             34 :                 break;
                                622                 :                : 
 4600 andrew@dunslane.net       623                 :             12 :             case 'j':           /* number of dump jobs */
 1556 michael@paquier.xyz       624         [ +  + ]:             12 :                 if (!option_parse_int(optarg, "-j/--jobs", 1,
                                625                 :                :                                       PG_MAX_JOBS,
                                626                 :                :                                       &numWorkers))
                                627                 :              1 :                     exit_nicely(1);
 4600 andrew@dunslane.net       628                 :             11 :                 break;
                                629                 :                : 
 6958 tgl@sss.pgh.pa.us         630                 :             17 :             case 'n':           /* include schema(s) */
                                631                 :             17 :                 simple_string_list_append(&schema_include_patterns, optarg);
 3942                           632                 :             17 :                 dopt.include_everything = false;
 6958                           633                 :             17 :                 break;
                                634                 :                : 
                                635                 :              1 :             case 'N':           /* exclude schema(s) */
                                636                 :              1 :                 simple_string_list_append(&schema_exclude_patterns, optarg);
 8292 bruce@momjian.us          637                 :              1 :                 break;
                                638                 :                : 
 8571 tgl@sss.pgh.pa.us         639                 :              2 :             case 'O':           /* Don't reconnect to match owner */
 3942                           640                 :              2 :                 dopt.outputNoOwner = 1;
 8571                           641                 :              2 :                 break;
                                642                 :                : 
                                643                 :             73 :             case 'p':           /* server port */
 1859                           644                 :             73 :                 dopt.cparams.pgport = pg_strdup(optarg);
 8571                           645                 :             73 :                 break;
                                646                 :                : 
 8070                           647                 :              2 :             case 'R':
                                648                 :                :                 /* no-op, still accepted for backwards compatibility */
 8571                           649                 :              2 :                 break;
                                650                 :                : 
                                651                 :              7 :             case 's':           /* dump schema only */
  336 nathan@postgresql.or      652                 :              7 :                 schema_only = true;
 8571 tgl@sss.pgh.pa.us         653                 :              7 :                 break;
                                654                 :                : 
 7317 bruce@momjian.us          655                 :              1 :             case 'S':           /* Username for superuser in plain text output */
 3942 tgl@sss.pgh.pa.us         656                 :              1 :                 dopt.outputSuperuser = pg_strdup(optarg);
 8571                           657                 :              1 :                 break;
                                658                 :                : 
 6958                           659                 :              8 :             case 't':           /* include table(s) */
                                660                 :              8 :                 simple_string_list_append(&table_include_patterns, optarg);
 3942                           661                 :              8 :                 dopt.include_everything = false;
 6958                           662                 :              8 :                 break;
                                663                 :                : 
                                664                 :              4 :             case 'T':           /* exclude table(s) */
                                665                 :              4 :                 simple_string_list_append(&table_exclude_patterns, optarg);
                                666                 :              4 :                 break;
                                667                 :                : 
 8571                           668                 :             36 :             case 'U':
 1859                           669                 :             36 :                 dopt.cparams.username = pg_strdup(optarg);
 8571                           670                 :             36 :                 break;
                                671                 :                : 
                                672                 :              6 :             case 'v':           /* verbose */
                                673                 :              6 :                 g_verbose = true;
 1866                           674                 :              6 :                 pg_logging_increase_verbosity();
 8571                           675                 :              6 :                 break;
                                676                 :                : 
 6087 peter_e@gmx.net           677                 :              1 :             case 'w':
 1859 tgl@sss.pgh.pa.us         678                 :              1 :                 dopt.cparams.promptPassword = TRI_NO;
 6087 peter_e@gmx.net           679                 :              1 :                 break;
                                680                 :                : 
 8571 tgl@sss.pgh.pa.us         681                 :UBC           0 :             case 'W':
 1859                           682                 :              0 :                 dopt.cparams.promptPassword = TRI_YES;
 8571                           683                 :              0 :                 break;
                                684                 :                : 
 8571 tgl@sss.pgh.pa.us         685                 :CBC           2 :             case 'x':           /* skip ACL dump */
 3942                           686                 :              2 :                 dopt.aclsSkip = true;
 8571                           687                 :              2 :                 break;
                                688                 :                : 
 1060 michael@paquier.xyz       689                 :             16 :             case 'Z':           /* Compression */
                                690                 :             16 :                 parse_compress_options(optarg, &compression_algorithm_str,
                                691                 :                :                                        &compression_detail);
                                692                 :             16 :                 user_compression_defined = true;
 8571 tgl@sss.pgh.pa.us         693                 :             16 :                 break;
                                694                 :                : 
                                695                 :            129 :             case 0:
                                696                 :                :                 /* This covers the long options. */
                                697                 :            129 :                 break;
                                698                 :                : 
 6139                           699                 :              2 :             case 2:             /* lock-wait-timeout */
 3942                           700                 :              2 :                 dopt.lockWaitTimeout = pg_strdup(optarg);
 6308                           701                 :              2 :                 break;
                                702                 :                : 
 6139                           703                 :              3 :             case 3:             /* SET ROLE */
 4763 bruce@momjian.us          704                 :              3 :                 use_role = pg_strdup(optarg);
 6139 tgl@sss.pgh.pa.us         705                 :              3 :                 break;
                                706                 :                : 
 4887 bruce@momjian.us          707                 :              1 :             case 4:             /* exclude table(s) data */
 5066 andrew@dunslane.net       708                 :              1 :                 simple_string_list_append(&tabledata_exclude_patterns, optarg);
                                709                 :              1 :                 break;
                                710                 :                : 
 5064                           711                 :              6 :             case 5:             /* section */
 3942 tgl@sss.pgh.pa.us         712                 :              6 :                 set_dump_section(optarg, &dopt.dumpSections);
 5064 andrew@dunslane.net       713                 :              6 :                 break;
                                714                 :                : 
 3997 simon@2ndQuadrant.co      715                 :UBC           0 :             case 6:             /* snapshot */
                                716                 :              0 :                 dumpsnapshot = pg_strdup(optarg);
                                717                 :              0 :                 break;
                                718                 :                : 
 3141 andrew@dunslane.net       719                 :CBC         151 :             case 7:             /* no-sync */
                                720                 :            151 :                 dosync = false;
                                721                 :            151 :                 break;
                                722                 :                : 
 2443                           723                 :              1 :             case 8:
                                724                 :              1 :                 have_extra_float_digits = true;
 1556 michael@paquier.xyz       725         [ +  - ]:              1 :                 if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
                                726                 :                :                                       &extra_float_digits))
 2443 andrew@dunslane.net       727                 :              1 :                     exit_nicely(1);
 2443 andrew@dunslane.net       728                 :UBC           0 :                 break;
                                729                 :                : 
 2426 alvherre@alvh.no-ip.      730                 :CBC           2 :             case 9:             /* inserts */
                                731                 :                : 
                                732                 :                :                 /*
                                733                 :                :                  * dump_inserts also stores --rows-per-insert, careful not to
                                734                 :                :                  * overwrite that.
                                735                 :                :                  */
                                736         [ +  - ]:              2 :                 if (dopt.dump_inserts == 0)
                                737                 :              2 :                     dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT;
                                738                 :              2 :                 break;
                                739                 :                : 
                                740                 :              2 :             case 10:            /* rows per insert */
 1556 michael@paquier.xyz       741         [ +  + ]:              2 :                 if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
                                742                 :                :                                       &dopt.dump_inserts))
 2426 alvherre@alvh.no-ip.      743                 :              1 :                     exit_nicely(1);
                                744                 :              1 :                 break;
                                745                 :                : 
 2042                           746                 :              4 :             case 11:            /* include foreign data */
                                747                 :              4 :                 simple_string_list_append(&foreign_servers_include_patterns,
                                748                 :                :                                           optarg);
                                749                 :              4 :                 break;
                                750                 :                : 
  958 tgl@sss.pgh.pa.us         751                 :              1 :             case 12:            /* include table(s) and their children */
                                752                 :              1 :                 simple_string_list_append(&table_include_patterns_and_children,
                                753                 :                :                                           optarg);
                                754                 :              1 :                 dopt.include_everything = false;
                                755                 :              1 :                 break;
                                756                 :                : 
                                757                 :              1 :             case 13:            /* exclude table(s) and their children */
                                758                 :              1 :                 simple_string_list_append(&table_exclude_patterns_and_children,
                                759                 :                :                                           optarg);
                                760                 :              1 :                 break;
                                761                 :                : 
                                762                 :              1 :             case 14:            /* exclude data of table(s) and children */
                                763                 :              1 :                 simple_string_list_append(&tabledata_exclude_patterns_and_children,
                                764                 :                :                                           optarg);
                                765                 :              1 :                 break;
                                766                 :                : 
  782 nathan@postgresql.or      767                 :UBC           0 :             case 15:
                                768         [ #  # ]:              0 :                 if (!parse_sync_method(optarg, &sync_method))
                                769                 :              0 :                     exit_nicely(1);
                                770                 :              0 :                 break;
                                771                 :                : 
  698 dgustafsson@postgres      772                 :CBC          26 :             case 16:            /* read object filters from file */
                                773                 :             26 :                 read_dump_filters(optarg, &dopt);
                                774                 :             22 :                 break;
                                775                 :                : 
  586 dean.a.rasheed@gmail      776                 :              1 :             case 17:            /* exclude extension(s) */
                                777                 :              1 :                 simple_string_list_append(&extension_exclude_patterns,
                                778                 :                :                                           optarg);
                                779                 :              1 :                 break;
                                780                 :                : 
  249 jdavis@postgresql.or      781                 :              4 :             case 18:
                                782                 :              4 :                 statistics_only = true;
                                783                 :              4 :                 break;
                                784                 :                : 
                                785                 :             36 :             case 19:
                                786                 :             36 :                 no_data = true;
                                787                 :             36 :                 break;
                                788                 :                : 
                                789                 :              2 :             case 20:
                                790                 :              2 :                 no_schema = true;
                                791                 :              2 :                 break;
                                792                 :                : 
                                793                 :              8 :             case 21:
                                794                 :              8 :                 no_statistics = true;
                                795                 :              8 :                 break;
                                796                 :                : 
  216                           797                 :             91 :             case 22:
                                798                 :             91 :                 with_statistics = true;
                                799                 :             91 :                 break;
                                800                 :                : 
   77 nathan@postgresql.or      801                 :             26 :             case 25:
                                802                 :             26 :                 dopt.restrict_key = pg_strdup(optarg);
                                803                 :             26 :                 break;
                                804                 :                : 
 8571 tgl@sss.pgh.pa.us         805                 :              1 :             default:
                                806                 :                :                 /* getopt_long already emitted a complaint */
 1298                           807                 :              1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 5002 rhaas@postgresql.org      808                 :              1 :                 exit_nicely(1);
                                809                 :                :         }
                                810                 :                :     }
                                811                 :                : 
                                812                 :                :     /*
                                813                 :                :      * Non-option argument specifies database name as long as it wasn't
                                814                 :                :      * already specified with -d / --dbname
                                815                 :                :      */
 1859 tgl@sss.pgh.pa.us         816   [ +  +  +  - ]:            226 :     if (optind < argc && dopt.cparams.dbname == NULL)
                                817                 :            190 :         dopt.cparams.dbname = argv[optind++];
                                818                 :                : 
                                819                 :                :     /* Complain if any arguments remain */
 5554                           820         [ +  + ]:            226 :     if (optind < argc)
                                821                 :                :     {
 2401 peter@eisentraut.org      822                 :              1 :         pg_log_error("too many command-line arguments (first is \"%s\")",
                                823                 :                :                      argv[optind]);
 1298 tgl@sss.pgh.pa.us         824                 :              1 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 5002 rhaas@postgresql.org      825                 :              1 :         exit_nicely(1);
                                826                 :                :     }
                                827                 :                : 
                                828                 :                :     /* --column-inserts implies --inserts */
 2426 alvherre@alvh.no-ip.      829   [ +  +  +  - ]:            225 :     if (dopt.column_inserts && dopt.dump_inserts == 0)
                                830                 :              1 :         dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT;
                                831                 :                : 
                                832                 :                :     /* reject conflicting "-only" options */
  336 nathan@postgresql.or      833   [ +  +  +  + ]:            225 :     if (data_only && schema_only)
 1298 tgl@sss.pgh.pa.us         834                 :              1 :         pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
  249 jdavis@postgresql.or      835   [ +  +  +  + ]:            224 :     if (schema_only && statistics_only)
                                836                 :              1 :         pg_fatal("options -s/--schema-only and --statistics-only cannot be used together");
                                837   [ +  +  +  + ]:            223 :     if (data_only && statistics_only)
                                838                 :              1 :         pg_fatal("options -a/--data-only and --statistics-only cannot be used together");
                                839                 :                : 
                                840                 :                :     /* reject conflicting "-only" and "no-" options */
                                841   [ +  +  -  + ]:            222 :     if (data_only && no_data)
  249 jdavis@postgresql.or      842                 :UBC           0 :         pg_fatal("options -a/--data-only and --no-data cannot be used together");
  249 jdavis@postgresql.or      843   [ +  +  -  + ]:CBC         222 :     if (schema_only && no_schema)
  249 jdavis@postgresql.or      844                 :UBC           0 :         pg_fatal("options -s/--schema-only and --no-schema cannot be used together");
  249 jdavis@postgresql.or      845   [ +  +  +  + ]:CBC         222 :     if (statistics_only && no_statistics)
                                846                 :              1 :         pg_fatal("options --statistics-only and --no-statistics cannot be used together");
                                847                 :                : 
                                848                 :                :     /* reject conflicting "no-" options */
  216                           849   [ +  +  -  + ]:            221 :     if (with_statistics && no_statistics)
   86 jdavis@postgresql.or      850                 :UBC           0 :         pg_fatal("options --statistics and --no-statistics cannot be used together");
                                851                 :                : 
                                852                 :                :     /* reject conflicting "-only" options */
   86 jdavis@postgresql.or      853   [ +  +  -  + ]:CBC         221 :     if (data_only && with_statistics)
   87 jdavis@postgresql.or      854                 :UBC           0 :         pg_fatal("options %s and %s cannot be used together",
                                855                 :                :                  "-a/--data-only", "--statistics");
   86 jdavis@postgresql.or      856   [ +  +  +  + ]:CBC         221 :     if (schema_only && with_statistics)
   87                           857                 :              1 :         pg_fatal("options %s and %s cannot be used together",
                                858                 :                :                  "-s/--schema-only", "--statistics");
                                859                 :                : 
  336 nathan@postgresql.or      860   [ +  +  +  + ]:            220 :     if (schema_only && foreign_servers_include_patterns.head != NULL)
 1298 tgl@sss.pgh.pa.us         861                 :              1 :         pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
                                862                 :                : 
 2042 alvherre@alvh.no-ip.      863   [ +  +  +  + ]:            219 :     if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
 1298 tgl@sss.pgh.pa.us         864                 :              1 :         pg_fatal("option --include-foreign-data is not supported with parallel backup");
                                865                 :                : 
  336 nathan@postgresql.or      866   [ +  +  +  + ]:            218 :     if (data_only && dopt.outputClean)
 1298 tgl@sss.pgh.pa.us         867                 :              1 :         pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
                                868                 :                : 
 3942                           869   [ +  +  +  + ]:            217 :     if (dopt.if_exists && !dopt.outputClean)
 1298                           870                 :              1 :         pg_fatal("option --if-exists requires option -c/--clean");
                                871                 :                : 
                                872                 :                :     /*
                                873                 :                :      * Set derivative flags. Ambiguous or nonsensical combinations, e.g.
                                874                 :                :      * "--schema-only --no-schema", will have already caused an error in one
                                875                 :                :      * of the checks above.
                                876                 :                :      */
  216 jdavis@postgresql.or      877   [ +  +  +  +  :            216 :     dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) ||
                                              -  + ]
   86                           878   [ +  -  +  + ]:            432 :                      data_only) && !no_data;
  216                           879   [ +  +  +  +  :            216 :     dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) ||
                                              -  + ]
   86                           880   [ +  -  +  + ]:            432 :                        schema_only) && !no_schema;
  216                           881   [ -  -  -  -  :            216 :     dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) ||
                                              +  + ]
                                882   [ -  +  +  +  :            432 :                            (statistics_only || with_statistics)) && !no_statistics;
                                              +  - ]
                                883                 :                : 
                                884                 :                : 
                                885                 :                :     /*
                                886                 :                :      * --inserts are already implied above if --column-inserts or
                                887                 :                :      * --rows-per-insert were specified.
                                888                 :                :      */
 2426 alvherre@alvh.no-ip.      889   [ +  +  +  - ]:            216 :     if (dopt.do_nothing && dopt.dump_inserts == 0)
 1298 tgl@sss.pgh.pa.us         890                 :              1 :         pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
                                891                 :                : 
                                892                 :                :     /* Identify archive format to emit */
 5391 heikki.linnakangas@i      893                 :            215 :     archiveFormat = parseArchiveFormat(format, &archiveMode);
                                894                 :                : 
                                895                 :                :     /* archiveFormat specific setup */
                                896         [ +  + ]:            214 :     if (archiveFormat == archNull)
                                897                 :                :     {
 6794 bruce@momjian.us          898                 :            155 :         plainText = 1;
                                899                 :                : 
                                900                 :                :         /*
                                901                 :                :          * If you don't provide a restrict key, one will be appointed for you.
                                902                 :                :          */
   77 nathan@postgresql.or      903         [ +  + ]:            155 :         if (!dopt.restrict_key)
                                904                 :            129 :             dopt.restrict_key = generate_restrict_key();
                                905         [ -  + ]:            155 :         if (!dopt.restrict_key)
   77 nathan@postgresql.or      906                 :UBC           0 :             pg_fatal("could not generate restrict key");
   77 nathan@postgresql.or      907         [ -  + ]:CBC         155 :         if (!valid_restrict_key(dopt.restrict_key))
   77 nathan@postgresql.or      908                 :UBC           0 :             pg_fatal("invalid restrict key");
                                909                 :                :     }
   77 nathan@postgresql.or      910         [ -  + ]:CBC          59 :     else if (dopt.restrict_key)
   77 nathan@postgresql.or      911                 :UBC           0 :         pg_fatal("option --restrict-key can only be used with --format=plain");
                                912                 :                : 
                                913                 :                :     /*
                                914                 :                :      * Custom and directory formats are compressed by default with gzip when
                                915                 :                :      * available, not the others.  If gzip is not available, no compression is
                                916                 :                :      * done by default.
                                917                 :                :      */
  914 michael@paquier.xyz       918   [ +  +  +  + ]:CBC         214 :     if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
                                919         [ +  + ]:             56 :         !user_compression_defined)
                                920                 :                :     {
                                921                 :                : #ifdef HAVE_LIBZ
                                922                 :             48 :         compression_algorithm_str = "gzip";
                                923                 :                : #else
                                924                 :                :         compression_algorithm_str = "none";
                                925                 :                : #endif
                                926                 :                :     }
                                927                 :                : 
                                928                 :                :     /*
                                929                 :                :      * Compression options
                                930                 :                :      */
 1060                           931         [ +  + ]:            214 :     if (!parse_compress_algorithm(compression_algorithm_str,
                                932                 :                :                                   &compression_algorithm))
                                933                 :              1 :         pg_fatal("unrecognized compression algorithm: \"%s\"",
                                934                 :                :                  compression_algorithm_str);
                                935                 :                : 
                                936                 :            213 :     parse_compress_specification(compression_algorithm, compression_detail,
                                937                 :                :                                  &compression_spec);
                                938                 :            213 :     error_detail = validate_compress_specification(&compression_spec);
                                939         [ +  + ]:            213 :     if (error_detail != NULL)
                                940                 :              3 :         pg_fatal("invalid compression specification: %s",
                                941                 :                :                  error_detail);
                                942                 :                : 
  936 tomas.vondra@postgre      943                 :            210 :     error_detail = supports_compression(compression_spec);
                                944         [ -  + ]:            210 :     if (error_detail != NULL)
  936 tomas.vondra@postgre      945                 :UBC           0 :         pg_fatal("%s", error_detail);
                                946                 :                : 
                                947                 :                :     /*
                                948                 :                :      * Disable support for zstd workers for now - these are based on
                                949                 :                :      * threading, and it's unclear how it interacts with parallel dumps on
                                950                 :                :      * platforms where that relies on threads too (e.g. Windows).
                                951                 :                :      */
  936 tomas.vondra@postgre      952         [ -  + ]:CBC         210 :     if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
  936 tomas.vondra@postgre      953                 :UBC           0 :         pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
                                954                 :                :                        "workers");
                                955                 :                : 
                                956                 :                :     /*
                                957                 :                :      * If emitting an archive format, we always want to emit a DATABASE item,
                                958                 :                :      * in case --create is specified at pg_restore time.
                                959                 :                :      */
 2832 tgl@sss.pgh.pa.us         960         [ +  + ]:CBC         210 :     if (!plainText)
                                961                 :             59 :         dopt.outputCreateDB = 1;
                                962                 :                : 
                                963                 :                :     /* Parallel backup only in the directory archive format so far */
 4600 andrew@dunslane.net       964   [ +  +  +  + ]:            210 :     if (archiveFormat != archDirectory && numWorkers > 1)
 1298 tgl@sss.pgh.pa.us         965                 :              1 :         pg_fatal("parallel backup only supported by the directory format");
                                966                 :                : 
                                967                 :                :     /* Open the output file */
 1060 michael@paquier.xyz       968                 :            209 :     fout = CreateArchive(filename, archiveFormat, compression_spec,
                                969                 :                :                          dosync, archiveMode, setupDumpWorker, sync_method);
                                970                 :                : 
                                971                 :                :     /* Make dump options accessible right away */
 3575 tgl@sss.pgh.pa.us         972                 :            208 :     SetArchiveOptions(fout, &dopt, NULL);
                                973                 :                : 
                                974                 :                :     /* Register the cleanup hook */
 4969 alvherre@alvh.no-ip.      975                 :            208 :     on_exit_close_archive(fout);
                                976                 :                : 
                                977                 :                :     /* Let the archiver know how noisy to be */
 5012 rhaas@postgresql.org      978                 :            208 :     fout->verbose = g_verbose;
                                979                 :                : 
                                980                 :                : 
                                981                 :                :     /*
                                982                 :                :      * We allow the server to be back to 9.2, and up to any minor release of
                                983                 :                :      * our own major version.  (See also version check in pg_dumpall.c.)
                                984                 :                :      */
 1413 tgl@sss.pgh.pa.us         985                 :            208 :     fout->minRemoteVersion = 90200;
 4598 heikki.linnakangas@i      986                 :            208 :     fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
                                987                 :                : 
 4600 andrew@dunslane.net       988                 :            208 :     fout->numWorkers = numWorkers;
                                989                 :                : 
                                990                 :                :     /*
                                991                 :                :      * Open the database using the Archiver, so it knows about it. Errors mean
                                992                 :                :      * death.
                                993                 :                :      */
  206                           994                 :            208 :     ConnectDatabaseAhx(fout, &dopt.cparams, false);
 3575 tgl@sss.pgh.pa.us         995                 :            206 :     setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
                                996                 :                : 
                                997                 :                :     /*
                                998                 :                :      * On hot standbys, never try to dump unlogged table data, since it will
                                999                 :                :      * just throw an error.
                               1000                 :                :      */
 3441 magnus@hagander.net      1001         [ +  + ]:            206 :     if (fout->isStandby)
                               1002                 :              4 :         dopt.no_unlogged_table_data = true;
                               1003                 :                : 
                               1004                 :                :     /*
                               1005                 :                :      * Find the last built-in OID, if needed (prior to 8.1)
                               1006                 :                :      *
                               1007                 :                :      * With 8.1 and above, we can just use FirstNormalObjectId - 1.
                               1008                 :                :      */
 1413 tgl@sss.pgh.pa.us        1009                 :            206 :     g_last_builtin_oid = FirstNormalObjectId - 1;
                               1010                 :                : 
 2401 peter@eisentraut.org     1011                 :            206 :     pg_log_info("last built-in OID is %u", g_last_builtin_oid);
                               1012                 :                : 
                               1013                 :                :     /* Expand schema selection patterns into OID lists */
 6958 tgl@sss.pgh.pa.us        1014         [ +  + ]:            206 :     if (schema_include_patterns.head != NULL)
                               1015                 :                :     {
 5012 rhaas@postgresql.org     1016                 :             18 :         expand_schema_name_patterns(fout, &schema_include_patterns,
                               1017                 :                :                                     &schema_include_oids,
                               1018                 :                :                                     strict_names);
 6958 tgl@sss.pgh.pa.us        1019         [ +  + ]:             12 :         if (schema_include_oids.head == NULL)
 1298                          1020                 :              1 :             pg_fatal("no matching schemas were found");
                               1021                 :                :     }
 5012 rhaas@postgresql.org     1022                 :            199 :     expand_schema_name_patterns(fout, &schema_exclude_patterns,
                               1023                 :                :                                 &schema_exclude_oids,
                               1024                 :                :                                 false);
                               1025                 :                :     /* non-matching exclusion patterns aren't an error */
                               1026                 :                : 
                               1027                 :                :     /* Expand table selection patterns into OID lists */
  958 tgl@sss.pgh.pa.us        1028                 :            199 :     expand_table_name_patterns(fout, &table_include_patterns,
                               1029                 :                :                                &table_include_oids,
                               1030                 :                :                                strict_names, false);
                               1031                 :            194 :     expand_table_name_patterns(fout, &table_include_patterns_and_children,
                               1032                 :                :                                &table_include_oids,
                               1033                 :                :                                strict_names, true);
                               1034         [ +  + ]:            194 :     if ((table_include_patterns.head != NULL ||
                               1035         [ +  + ]:            183 :          table_include_patterns_and_children.head != NULL) &&
                               1036         [ +  + ]:             13 :         table_include_oids.head == NULL)
                               1037                 :              2 :         pg_fatal("no matching tables were found");
                               1038                 :                : 
 5011 rhaas@postgresql.org     1039                 :            192 :     expand_table_name_patterns(fout, &table_exclude_patterns,
                               1040                 :                :                                &table_exclude_oids,
                               1041                 :                :                                false, false);
  958 tgl@sss.pgh.pa.us        1042                 :            192 :     expand_table_name_patterns(fout, &table_exclude_patterns_and_children,
                               1043                 :                :                                &table_exclude_oids,
                               1044                 :                :                                false, true);
                               1045                 :                : 
 5011 rhaas@postgresql.org     1046                 :            192 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns,
                               1047                 :                :                                &tabledata_exclude_oids,
                               1048                 :                :                                false, false);
  958 tgl@sss.pgh.pa.us        1049                 :            192 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns_and_children,
                               1050                 :                :                                &tabledata_exclude_oids,
                               1051                 :                :                                false, true);
                               1052                 :                : 
 2042 alvherre@alvh.no-ip.     1053                 :            192 :     expand_foreign_server_name_patterns(fout, &foreign_servers_include_patterns,
                               1054                 :                :                                         &foreign_servers_include_oids);
                               1055                 :                : 
                               1056                 :                :     /* non-matching exclusion patterns aren't an error */
                               1057                 :                : 
                               1058                 :                :     /* Expand extension selection patterns into OID lists */
 1671 michael@paquier.xyz      1059         [ +  + ]:            191 :     if (extension_include_patterns.head != NULL)
                               1060                 :                :     {
                               1061                 :              5 :         expand_extension_name_patterns(fout, &extension_include_patterns,
                               1062                 :                :                                        &extension_include_oids,
                               1063                 :                :                                        strict_names);
                               1064         [ +  + ]:              5 :         if (extension_include_oids.head == NULL)
 1298 tgl@sss.pgh.pa.us        1065                 :              1 :             pg_fatal("no matching extensions were found");
                               1066                 :                :     }
  586 dean.a.rasheed@gmail     1067                 :            190 :     expand_extension_name_patterns(fout, &extension_exclude_patterns,
                               1068                 :                :                                    &extension_exclude_oids,
                               1069                 :                :                                    false);
                               1070                 :                :     /* non-matching exclusion patterns aren't an error */
                               1071                 :                : 
                               1072                 :                :     /*
                               1073                 :                :      * Dumping LOs is the default for dumps where an inclusion switch is not
                               1074                 :                :      * used (an "include everything" dump).  -B can be used to exclude LOs
                               1075                 :                :      * from those dumps.  -b can be used to include LOs even when an inclusion
                               1076                 :                :      * switch is used.
                               1077                 :                :      *
                               1078                 :                :      * -s means "schema only" and LOs are data, not schema, so we never
                               1079                 :                :      * include LOs when -s is used.
                               1080                 :                :      */
  336 nathan@postgresql.or     1081   [ +  +  +  +  :            190 :     if (dopt.include_everything && dopt.dumpData && !dopt.dontOutputLOs)
                                              +  + ]
 1057 peter@eisentraut.org     1082                 :            125 :         dopt.outputLOs = true;
                               1083                 :                : 
                               1084                 :                :     /*
                               1085                 :                :      * Collect role names so we can map object owner OIDs to names.
                               1086                 :                :      */
 1396 tgl@sss.pgh.pa.us        1087                 :            190 :     collectRoleNames(fout);
                               1088                 :                : 
                               1089                 :                :     /*
                               1090                 :                :      * Now scan the database and create DumpableObject structs for all the
                               1091                 :                :      * objects we intend to dump.
                               1092                 :                :      */
 3575                          1093                 :            190 :     tblinfo = getSchemaData(fout, &numTables);
                               1094                 :                : 
  336 nathan@postgresql.or     1095         [ +  + ]:            189 :     if (dopt.dumpData)
                               1096                 :                :     {
 2533 andres@anarazel.de       1097                 :            149 :         getTableData(&dopt, tblinfo, numTables, 0);
 4621 kgrittn@postgresql.o     1098                 :            149 :         buildMatViewRefreshDependencies(fout);
  336 nathan@postgresql.or     1099         [ +  + ]:            149 :         if (!dopt.dumpSchema)
 6258 tgl@sss.pgh.pa.us        1100                 :              7 :             getTableDataFKConstraints();
                               1101                 :                :     }
                               1102                 :                : 
  336 nathan@postgresql.or     1103   [ +  +  +  + ]:            189 :     if (!dopt.dumpData && dopt.sequence_data)
 2533 andres@anarazel.de       1104                 :             32 :         getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
                               1105                 :                : 
                               1106                 :                :     /*
                               1107                 :                :      * For binary upgrade mode, dump pg_largeobject_metadata and the
                               1108                 :                :      * associated pg_shdepend rows. This is faster to restore than the
                               1109                 :                :      * equivalent set of large object commands.  We can only do this for
                               1110                 :                :      * upgrades from v12 and newer; in older versions, pg_largeobject_metadata
                               1111                 :                :      * was created WITH OIDS, so the OID column is hidden and won't be dumped.
                               1112                 :                :      */
  101 nathan@postgresql.or     1113   [ +  +  +  - ]:GNC         189 :     if (dopt.binary_upgrade && fout->remoteVersion >= 120000)
                               1114                 :                :     {
                               1115                 :             36 :         TableInfo  *lo_metadata = findTableByOid(LargeObjectMetadataRelationId);
                               1116                 :             36 :         TableInfo  *shdepend = findTableByOid(SharedDependRelationId);
                               1117                 :                : 
                               1118                 :             36 :         makeTableDataInfo(&dopt, lo_metadata);
                               1119                 :             36 :         makeTableDataInfo(&dopt, shdepend);
                               1120                 :                : 
                               1121                 :                :         /*
                               1122                 :                :          * Save pg_largeobject_metadata's dump ID for use as a dependency for
                               1123                 :                :          * pg_shdepend and any large object comments/seclabels.
                               1124                 :                :          */
                               1125                 :             36 :         lo_metadata_dumpId = lo_metadata->dataObj->dobj.dumpId;
                               1126                 :             36 :         addObjectDependency(&shdepend->dataObj->dobj, lo_metadata_dumpId);
                               1127                 :                : 
                               1128                 :                :         /*
                               1129                 :                :          * Only dump large object shdepend rows for this database.
                               1130                 :                :          */
                               1131                 :             36 :         shdepend->dataObj->filtercond = "WHERE classid = 'pg_largeobject'::regclass "
                               1132                 :                :             "AND dbid = (SELECT oid FROM pg_database "
                               1133                 :                :             "            WHERE datname = current_database())";
                               1134                 :                : 
                               1135                 :                :         /*
                               1136                 :                :          * If upgrading from v16 or newer, only dump large objects with
                               1137                 :                :          * comments/seclabels.  For these upgrades, pg_upgrade can copy/link
                               1138                 :                :          * pg_largeobject_metadata's files (which is usually faster) but we
                               1139                 :                :          * still need to dump LOs with comments/seclabels here so that the
                               1140                 :                :          * subsequent COMMENT and SECURITY LABEL commands work.  pg_upgrade
                               1141                 :                :          * can't copy/link the files from older versions because aclitem
                               1142                 :                :          * (needed by pg_largeobject_metadata.lomacl) changed its storage
                               1143                 :                :          * format in v16.
                               1144                 :                :          */
   49                          1145         [ +  - ]:             36 :         if (fout->remoteVersion >= 160000)
                               1146                 :             36 :             lo_metadata->dataObj->filtercond = "WHERE oid IN "
                               1147                 :                :                 "(SELECT objoid FROM pg_description "
                               1148                 :                :                 "WHERE classoid = " CppAsString2(LargeObjectRelationId) " "
                               1149                 :                :                 "UNION SELECT objoid FROM pg_seclabel "
                               1150                 :                :                 "WHERE classoid = " CppAsString2(LargeObjectRelationId) ")";
                               1151                 :                :     }
                               1152                 :                : 
                               1153                 :                :     /*
                               1154                 :                :      * In binary-upgrade mode, we do not have to worry about the actual LO
                               1155                 :                :      * data or the associated metadata that resides in the pg_largeobject and
                               1156                 :                :      * pg_largeobject_metadata tables, respectively.
                               1157                 :                :      *
                               1158                 :                :      * However, we do need to collect LO information as there may be comments
                               1159                 :                :      * or other information on LOs that we do need to dump out.
                               1160                 :                :      */
 1057 peter@eisentraut.org     1161   [ +  +  +  + ]:CBC         189 :     if (dopt.outputLOs || dopt.binary_upgrade)
                               1162                 :            161 :         getLOs(fout);
                               1163                 :                : 
                               1164                 :                :     /*
                               1165                 :                :      * Collect dependency data to assist in ordering the objects.
                               1166                 :                :      */
 5012 rhaas@postgresql.org     1167                 :            189 :     getDependencies(fout);
                               1168                 :                : 
                               1169                 :                :     /*
                               1170                 :                :      * Collect ACLs, comments, and security labels, if wanted.
                               1171                 :                :      */
 1421 tgl@sss.pgh.pa.us        1172         [ +  + ]:            189 :     if (!dopt.aclsSkip)
                               1173                 :            187 :         getAdditionalACLs(fout);
                               1174         [ +  - ]:            189 :     if (!dopt.no_comments)
                               1175                 :            189 :         collectComments(fout);
                               1176         [ +  - ]:            189 :     if (!dopt.no_security_labels)
                               1177                 :            189 :         collectSecLabels(fout);
                               1178                 :                : 
                               1179                 :                :     /* For binary upgrade mode, collect required pg_class information. */
  481 nathan@postgresql.or     1180         [ +  + ]:            189 :     if (dopt.binary_upgrade)
                               1181                 :             36 :         collectBinaryUpgradeClassOids(fout);
                               1182                 :                : 
                               1183                 :                :     /* Collect sequence information. */
  453                          1184                 :            189 :     collectSequences(fout);
                               1185                 :                : 
                               1186                 :                :     /* Lastly, create dummy objects to represent the section boundaries */
 4872 tgl@sss.pgh.pa.us        1187                 :            189 :     boundaryObjs = createBoundaryObjects();
                               1188                 :                : 
                               1189                 :                :     /* Get pointers to all the known DumpableObjects */
                               1190                 :            189 :     getDumpableObjects(&dobjs, &numObjs);
                               1191                 :                : 
                               1192                 :                :     /*
                               1193                 :                :      * Add dummy dependencies to enforce the dump section ordering.
                               1194                 :                :      */
                               1195                 :            189 :     addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
                               1196                 :                : 
                               1197                 :                :     /*
                               1198                 :                :      * Sort the objects into a safe dump order (no forward references).
                               1199                 :                :      *
                               1200                 :                :      * We rely on dependency information to help us determine a safe order, so
                               1201                 :                :      * the initial sort is mostly for cosmetic purposes: we sort by name to
                               1202                 :                :      * ensure that logically identical schemas will dump identically.
                               1203                 :                :      */
 3302                          1204                 :            189 :     sortDumpableObjectsByTypeName(dobjs, numObjs);
                               1205                 :                : 
 4872                          1206                 :            189 :     sortDumpableObjects(dobjs, numObjs,
                               1207                 :            189 :                         boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
                               1208                 :                : 
                               1209                 :                :     /*
                               1210                 :                :      * Create archive TOC entries for all the objects to be dumped, in a safe
                               1211                 :                :      * order.
                               1212                 :                :      */
                               1213                 :                : 
                               1214                 :                :     /*
                               1215                 :                :      * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
                               1216                 :                :      */
 5012 rhaas@postgresql.org     1217                 :            189 :     dumpEncoding(fout);
                               1218                 :            189 :     dumpStdStrings(fout);
 2800 tgl@sss.pgh.pa.us        1219                 :            189 :     dumpSearchPath(fout);
                               1220                 :                : 
                               1221                 :                :     /* The database items are always next, unless we don't want them at all */
 2832                          1222         [ +  + ]:            189 :     if (dopt.outputCreateDB)
 3575                          1223                 :             87 :         dumpDatabase(fout);
                               1224                 :                : 
                               1225                 :                :     /* Now the rearrangeable objects. */
 7996                          1226         [ +  + ]:         832807 :     for (i = 0; i < numObjs; i++)
 3575                          1227                 :         832618 :         dumpDumpableObject(fout, dobjs[i]);
                               1228                 :                : 
                               1229                 :                :     /*
                               1230                 :                :      * Set up options info to ensure we dump what we want.
                               1231                 :                :      */
 4899                          1232                 :            189 :     ropt = NewRestoreOptions();
                               1233                 :            189 :     ropt->filename = filename;
                               1234                 :                : 
                               1235                 :                :     /* if you change this list, see dumpOptionsFromRestoreOptions */
 1859                          1236         [ +  + ]:            189 :     ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
                               1237         [ +  + ]:            189 :     ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
                               1238         [ +  + ]:            189 :     ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
                               1239         [ +  + ]:            189 :     ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
                               1240                 :            189 :     ropt->cparams.promptPassword = dopt.cparams.promptPassword;
 3942                          1241                 :            189 :     ropt->dropSchema = dopt.outputClean;
  336 nathan@postgresql.or     1242                 :            189 :     ropt->dumpData = dopt.dumpData;
                               1243                 :            189 :     ropt->dumpSchema = dopt.dumpSchema;
  249 jdavis@postgresql.or     1244                 :            189 :     ropt->dumpStatistics = dopt.dumpStatistics;
 3942 tgl@sss.pgh.pa.us        1245                 :            189 :     ropt->if_exists = dopt.if_exists;
                               1246                 :            189 :     ropt->column_inserts = dopt.column_inserts;
                               1247                 :            189 :     ropt->dumpSections = dopt.dumpSections;
                               1248                 :            189 :     ropt->aclsSkip = dopt.aclsSkip;
                               1249                 :            189 :     ropt->superuser = dopt.outputSuperuser;
                               1250                 :            189 :     ropt->createDB = dopt.outputCreateDB;
                               1251                 :            189 :     ropt->noOwner = dopt.outputNoOwner;
 1379 michael@paquier.xyz      1252                 :            189 :     ropt->noTableAm = dopt.outputNoTableAm;
 3942 tgl@sss.pgh.pa.us        1253                 :            189 :     ropt->noTablespace = dopt.outputNoTablespaces;
                               1254                 :            189 :     ropt->disable_triggers = dopt.disable_triggers;
                               1255                 :            189 :     ropt->use_setsessauth = dopt.use_setsessauth;
                               1256                 :            189 :     ropt->disable_dollar_quoting = dopt.disable_dollar_quoting;
                               1257                 :            189 :     ropt->dump_inserts = dopt.dump_inserts;
 2832                          1258                 :            189 :     ropt->no_comments = dopt.no_comments;
  225                          1259                 :            189 :     ropt->no_policies = dopt.no_policies;
 3090 peter_e@gmx.net          1260                 :            189 :     ropt->no_publications = dopt.no_publications;
 3942 tgl@sss.pgh.pa.us        1261                 :            189 :     ropt->no_security_labels = dopt.no_security_labels;
 3093 peter_e@gmx.net          1262                 :            189 :     ropt->no_subscriptions = dopt.no_subscriptions;
 3942 tgl@sss.pgh.pa.us        1263                 :            189 :     ropt->lockWaitTimeout = dopt.lockWaitTimeout;
                               1264                 :            189 :     ropt->include_everything = dopt.include_everything;
                               1265                 :            189 :     ropt->enable_row_security = dopt.enable_row_security;
 3352 peter_e@gmx.net          1266                 :            189 :     ropt->sequence_data = dopt.sequence_data;
 3157 sfrost@snowman.net       1267                 :            189 :     ropt->binary_upgrade = dopt.binary_upgrade;
   77 nathan@postgresql.or     1268         [ +  + ]:            189 :     ropt->restrict_key = dopt.restrict_key ? pg_strdup(dopt.restrict_key) : NULL;
                               1269                 :                : 
 1060 michael@paquier.xyz      1270                 :            189 :     ropt->compression_spec = compression_spec;
                               1271                 :                : 
 4887 bruce@momjian.us         1272                 :            189 :     ropt->suppressDumpWarnings = true;   /* We've already shown them */
                               1273                 :                : 
 3575 tgl@sss.pgh.pa.us        1274                 :            189 :     SetArchiveOptions(fout, &dopt, ropt);
                               1275                 :                : 
                               1276                 :                :     /* Mark which entries should be output */
                               1277                 :            189 :     ProcessArchiveRestoreOptions(fout);
                               1278                 :                : 
                               1279                 :                :     /*
                               1280                 :                :      * The archive's TOC entries are now marked as to which ones will actually
                               1281                 :                :      * be output, so we can set up their dependency lists properly. This isn't
                               1282                 :                :      * necessary for plain-text output, though.
                               1283                 :                :      */
 4872                          1284         [ +  + ]:            189 :     if (!plainText)
                               1285                 :             58 :         BuildArchiveDependencies(fout);
                               1286                 :                : 
                               1287                 :                :     /*
                               1288                 :                :      * And finally we can do the actual output.
                               1289                 :                :      *
                               1290                 :                :      * Note: for non-plain-text output formats, the output file is written
                               1291                 :                :      * inside CloseArchive().  This is, um, bizarre; but not worth changing
                               1292                 :                :      * right now.
                               1293                 :                :      */
 4899                          1294         [ +  + ]:            189 :     if (plainText)
   89 andrew@dunslane.net      1295                 :            131 :         RestoreArchive(fout);
                               1296                 :                : 
 3575 tgl@sss.pgh.pa.us        1297                 :            188 :     CloseArchive(fout);
                               1298                 :                : 
 5002 rhaas@postgresql.org     1299                 :            188 :     exit_nicely(0);
                               1300                 :                : }
                               1301                 :                : 
                               1302                 :                : 
                               1303                 :                : static void
 8571 tgl@sss.pgh.pa.us        1304                 :              1 : help(const char *progname)
                               1305                 :                : {
  130 peter@eisentraut.org     1306                 :              1 :     printf(_("%s exports a PostgreSQL database as an SQL script or to other formats.\n\n"), progname);
 8461 peter_e@gmx.net          1307                 :              1 :     printf(_("Usage:\n"));
 8410                          1308                 :              1 :     printf(_("  %s [OPTION]... [DBNAME]\n"), progname);
                               1309                 :                : 
                               1310                 :              1 :     printf(_("\nGeneral options:\n"));
 4910                          1311                 :              1 :     printf(_("  -f, --file=FILENAME          output file or directory name\n"));
                               1312                 :              1 :     printf(_("  -F, --format=c|d|t|p         output file format (custom, directory, tar,\n"
                               1313                 :                :              "                               plain text (default))\n"));
 4600 andrew@dunslane.net      1314                 :              1 :     printf(_("  -j, --jobs=NUM               use this many parallel jobs to dump\n"));
 4910 peter_e@gmx.net          1315                 :              1 :     printf(_("  -v, --verbose                verbose mode\n"));
 4879                          1316                 :              1 :     printf(_("  -V, --version                output version information, then exit\n"));
  892 peter@eisentraut.org     1317                 :              1 :     printf(_("  -Z, --compress=METHOD[:DETAIL]\n"
                               1318                 :                :              "                               compress as specified\n"));
 4910 peter_e@gmx.net          1319                 :              1 :     printf(_("  --lock-wait-timeout=TIMEOUT  fail after waiting TIMEOUT for a table lock\n"));
 3141 andrew@dunslane.net      1320                 :              1 :     printf(_("  --no-sync                    do not wait for changes to be written safely to disk\n"));
  782 nathan@postgresql.or     1321                 :              1 :     printf(_("  --sync-method=METHOD         set method for syncing files to disk\n"));
 4879 peter_e@gmx.net          1322                 :              1 :     printf(_("  -?, --help                   show this help, then exit\n"));
                               1323                 :                : 
 8410                          1324                 :              1 :     printf(_("\nOptions controlling the output content:\n"));
  249 jdavis@postgresql.or     1325                 :              1 :     printf(_("  -a, --data-only              dump only the data, not the schema or statistics\n"));
  892 peter@eisentraut.org     1326                 :              1 :     printf(_("  -b, --large-objects          include large objects in dump\n"));
                               1327                 :              1 :     printf(_("  --blobs                      (same as --large-objects, deprecated)\n"));
                               1328                 :              1 :     printf(_("  -B, --no-large-objects       exclude large objects in dump\n"));
                               1329                 :              1 :     printf(_("  --no-blobs                   (same as --no-large-objects, deprecated)\n"));
 4910 peter_e@gmx.net          1330                 :              1 :     printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
                               1331                 :              1 :     printf(_("  -C, --create                 include commands to create database in dump\n"));
 1671 michael@paquier.xyz      1332                 :              1 :     printf(_("  -e, --extension=PATTERN      dump the specified extension(s) only\n"));
 4910 peter_e@gmx.net          1333                 :              1 :     printf(_("  -E, --encoding=ENCODING      dump the data in encoding ENCODING\n"));
 2246 peter@eisentraut.org     1334                 :              1 :     printf(_("  -n, --schema=PATTERN         dump the specified schema(s) only\n"));
                               1335                 :              1 :     printf(_("  -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
 4910 peter_e@gmx.net          1336                 :              1 :     printf(_("  -O, --no-owner               skip restoration of object ownership in\n"
                               1337                 :                :              "                               plain-text format\n"));
  249 jdavis@postgresql.or     1338                 :              1 :     printf(_("  -s, --schema-only            dump only the schema, no data or statistics\n"));
 4910 peter_e@gmx.net          1339                 :              1 :     printf(_("  -S, --superuser=NAME         superuser user name to use in plain-text format\n"));
  958 tgl@sss.pgh.pa.us        1340                 :              1 :     printf(_("  -t, --table=PATTERN          dump only the specified table(s)\n"));
 2246 peter@eisentraut.org     1341                 :              1 :     printf(_("  -T, --exclude-table=PATTERN  do NOT dump the specified table(s)\n"));
 4910 peter_e@gmx.net          1342                 :              1 :     printf(_("  -x, --no-privileges          do not dump privileges (grant/revoke)\n"));
                               1343                 :              1 :     printf(_("  --binary-upgrade             for use by upgrade utilities only\n"));
                               1344                 :              1 :     printf(_("  --column-inserts             dump data as INSERT commands with column names\n"));
                               1345                 :              1 :     printf(_("  --disable-dollar-quoting     disable dollar quoting, use SQL standard quoting\n"));
                               1346                 :              1 :     printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
 3694                          1347                 :              1 :     printf(_("  --enable-row-security        enable row security (dump only content user has\n"
                               1348                 :                :              "                               access to)\n"));
  551 peter@eisentraut.org     1349                 :              1 :     printf(_("  --exclude-extension=PATTERN  do NOT dump the specified extension(s)\n"));
  958 tgl@sss.pgh.pa.us        1350                 :              1 :     printf(_("  --exclude-table-and-children=PATTERN\n"
                               1351                 :                :              "                               do NOT dump the specified table(s), including\n"
                               1352                 :                :              "                               child and partition tables\n"));
 2246 peter@eisentraut.org     1353                 :              1 :     printf(_("  --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
  958 tgl@sss.pgh.pa.us        1354                 :              1 :     printf(_("  --exclude-table-data-and-children=PATTERN\n"
                               1355                 :                :              "                               do NOT dump data for the specified table(s),\n"
                               1356                 :                :              "                               including child and partition tables\n"));
 2443 andrew@dunslane.net      1357                 :              1 :     printf(_("  --extra-float-digits=NUM     override default setting for extra_float_digits\n"));
  698 dgustafsson@postgres     1358                 :              1 :     printf(_("  --filter=FILENAME            include or exclude objects and data from dump\n"
                               1359                 :                :              "                               based on expressions in FILENAME\n"));
 4256 alvherre@alvh.no-ip.     1360                 :              1 :     printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
 2042                          1361                 :              1 :     printf(_("  --include-foreign-data=PATTERN\n"
                               1362                 :                :              "                               include data of foreign tables on foreign\n"
                               1363                 :                :              "                               servers matching PATTERN\n"));
 4910 peter_e@gmx.net          1364                 :              1 :     printf(_("  --inserts                    dump data as INSERT commands, rather than COPY\n"));
 2702                          1365                 :              1 :     printf(_("  --load-via-partition-root    load partitions via the root table\n"));
  341 bruce@momjian.us         1366                 :              1 :     printf(_("  --no-comments                do not dump comment commands\n"));
  249 jdavis@postgresql.or     1367                 :              1 :     printf(_("  --no-data                    do not dump data\n"));
  225 tgl@sss.pgh.pa.us        1368                 :              1 :     printf(_("  --no-policies                do not dump row security policies\n"));
 3090 peter_e@gmx.net          1369                 :              1 :     printf(_("  --no-publications            do not dump publications\n"));
  249 jdavis@postgresql.or     1370                 :              1 :     printf(_("  --no-schema                  do not dump schema\n"));
 4910 peter_e@gmx.net          1371                 :              1 :     printf(_("  --no-security-labels         do not dump security label assignments\n"));
  249 jdavis@postgresql.or     1372                 :              1 :     printf(_("  --no-statistics              do not dump statistics\n"));
 3093 peter_e@gmx.net          1373                 :              1 :     printf(_("  --no-subscriptions           do not dump subscriptions\n"));
 1379 michael@paquier.xyz      1374                 :              1 :     printf(_("  --no-table-access-method     do not dump table access methods\n"));
 4910 peter_e@gmx.net          1375                 :              1 :     printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
 1627 peter@eisentraut.org     1376                 :              1 :     printf(_("  --no-toast-compression       do not dump TOAST compression methods\n"));
 4910 peter_e@gmx.net          1377                 :              1 :     printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
 2663 tmunro@postgresql.or     1378                 :              1 :     printf(_("  --on-conflict-do-nothing     add ON CONFLICT DO NOTHING to INSERT commands\n"));
 4910 peter_e@gmx.net          1379                 :              1 :     printf(_("  --quote-all-identifiers      quote all identifiers, even if not key words\n"));
   77 nathan@postgresql.or     1380                 :              1 :     printf(_("  --restrict-key=RESTRICT_KEY  use provided string as psql \\restrict key\n"));
 2426 alvherre@alvh.no-ip.     1381                 :              1 :     printf(_("  --rows-per-insert=NROWS      number of rows per INSERT; implies --inserts\n"));
 4910 peter_e@gmx.net          1382                 :              1 :     printf(_("  --section=SECTION            dump named section (pre-data, data, or post-data)\n"));
  216 nathan@postgresql.or     1383                 :              1 :     printf(_("  --sequence-data              include sequence data in dump\n"));
 4910 peter_e@gmx.net          1384                 :              1 :     printf(_("  --serializable-deferrable    wait until the dump can run without anomalies\n"));
 3683                          1385                 :              1 :     printf(_("  --snapshot=SNAPSHOT          use given snapshot for the dump\n"));
   86 jdavis@postgresql.or     1386                 :              1 :     printf(_("  --statistics                 dump the statistics\n"));
  249                          1387                 :              1 :     printf(_("  --statistics-only            dump only the statistics, not schema or data\n"));
 3696 teodor@sigaev.ru         1388                 :              1 :     printf(_("  --strict-names               require table and/or schema include patterns to\n"
                               1389                 :                :              "                               match at least one entity each\n"));
  892 peter@eisentraut.org     1390                 :              1 :     printf(_("  --table-and-children=PATTERN dump only the specified table(s), including\n"
                               1391                 :                :              "                               child and partition tables\n"));
 6960 peter_e@gmx.net          1392                 :              1 :     printf(_("  --use-set-session-authorization\n"
                               1393                 :                :              "                               use SET SESSION AUTHORIZATION commands instead of\n"
                               1394                 :                :              "                               ALTER OWNER commands to set ownership\n"));
                               1395                 :                : 
 8410                          1396                 :              1 :     printf(_("\nConnection options:\n"));
 4627 heikki.linnakangas@i     1397                 :              1 :     printf(_("  -d, --dbname=DBNAME      database to dump\n"));
 8174 bruce@momjian.us         1398                 :              1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
 8410 peter_e@gmx.net          1399                 :              1 :     printf(_("  -p, --port=PORT          database server port number\n"));
                               1400                 :              1 :     printf(_("  -U, --username=NAME      connect as specified database user\n"));
 6068                          1401                 :              1 :     printf(_("  -w, --no-password        never prompt for password\n"));
 8410                          1402                 :              1 :     printf(_("  -W, --password           force password prompt (should happen automatically)\n"));
 5269                          1403                 :              1 :     printf(_("  --role=ROLENAME          do SET ROLE before dump\n"));
                               1404                 :                : 
 8132                          1405                 :              1 :     printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
                               1406                 :                :              "variable value is used.\n\n"));
 2068 peter@eisentraut.org     1407                 :              1 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
                               1408                 :              1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 8571 tgl@sss.pgh.pa.us        1409                 :              1 : }
                               1410                 :                : 
                               1411                 :                : static void
 3575                          1412                 :            224 : setup_connection(Archive *AH, const char *dumpencoding,
                               1413                 :                :                  const char *dumpsnapshot, char *use_role)
                               1414                 :                : {
                               1415                 :            224 :     DumpOptions *dopt = AH->dopt;
 5002 rhaas@postgresql.org     1416                 :            224 :     PGconn     *conn = GetConnection(AH);
                               1417                 :                :     const char *std_strings;
                               1418                 :                : 
 2800 noah@leadboat.com        1419                 :            224 :     PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL));
                               1420                 :                : 
                               1421                 :                :     /*
                               1422                 :                :      * Set the client encoding if requested.
                               1423                 :                :      */
 5022 rhaas@postgresql.org     1424         [ +  + ]:            224 :     if (dumpencoding)
                               1425                 :                :     {
 5002                          1426         [ -  + ]:             20 :         if (PQsetClientEncoding(conn, dumpencoding) < 0)
 1298 tgl@sss.pgh.pa.us        1427                 :UBC           0 :             pg_fatal("invalid client encoding \"%s\" specified",
                               1428                 :                :                      dumpencoding);
                               1429                 :                :     }
                               1430                 :                : 
                               1431                 :                :     /*
                               1432                 :                :      * Get the active encoding and the standard_conforming_strings setting, so
                               1433                 :                :      * we know how to escape strings.
                               1434                 :                :      */
 5002 rhaas@postgresql.org     1435                 :CBC         224 :     AH->encoding = PQclientEncoding(conn);
  259 andres@anarazel.de       1436                 :            224 :     setFmtEncoding(AH->encoding);
                               1437                 :                : 
 5002 rhaas@postgresql.org     1438                 :            224 :     std_strings = PQparameterStatus(conn, "standard_conforming_strings");
 5022                          1439   [ +  -  +  - ]:            224 :     AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
                               1440                 :                : 
                               1441                 :                :     /*
                               1442                 :                :      * Set the role if requested.  In a parallel dump worker, we'll be passed
                               1443                 :                :      * use_role == NULL, but AH->use_role is already set (if user specified it
                               1444                 :                :      * originally) and we should use that.
                               1445                 :                :      */
 4600 andrew@dunslane.net      1446   [ +  +  +  + ]:            224 :     if (!use_role && AH->use_role)
                               1447                 :              2 :         use_role = AH->use_role;
                               1448                 :                : 
                               1449                 :                :     /* Set the role if requested */
 1413 tgl@sss.pgh.pa.us        1450         [ +  + ]:            224 :     if (use_role)
                               1451                 :                :     {
 5022 rhaas@postgresql.org     1452                 :              5 :         PQExpBuffer query = createPQExpBuffer();
                               1453                 :                : 
                               1454                 :              5 :         appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
 5011                          1455                 :              5 :         ExecuteSqlStatement(AH, query->data);
 5022                          1456                 :              5 :         destroyPQExpBuffer(query);
                               1457                 :                : 
                               1458                 :                :         /* save it for possible later use by parallel workers */
 4600 andrew@dunslane.net      1459         [ +  + ]:              5 :         if (!AH->use_role)
 3435 tgl@sss.pgh.pa.us        1460                 :              3 :             AH->use_role = pg_strdup(use_role);
                               1461                 :                :     }
                               1462                 :                : 
                               1463                 :                :     /* Set the datestyle to ISO to ensure the dump's portability */
 5011 rhaas@postgresql.org     1464                 :            224 :     ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
                               1465                 :                : 
                               1466                 :                :     /* Likewise, avoid using sql_standard intervalstyle */
 1413 tgl@sss.pgh.pa.us        1467                 :            224 :     ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
                               1468                 :                : 
                               1469                 :                :     /*
                               1470                 :                :      * Use an explicitly specified extra_float_digits if it has been provided.
                               1471                 :                :      * Otherwise, set extra_float_digits so that we can dump float data
                               1472                 :                :      * exactly (given correctly implemented float I/O code, anyway).
                               1473                 :                :      */
 2443 andrew@dunslane.net      1474         [ -  + ]:            224 :     if (have_extra_float_digits)
                               1475                 :                :     {
 2443 andrew@dunslane.net      1476                 :UBC           0 :         PQExpBuffer q = createPQExpBuffer();
                               1477                 :                : 
                               1478                 :              0 :         appendPQExpBuffer(q, "SET extra_float_digits TO %d",
                               1479                 :                :                           extra_float_digits);
                               1480                 :              0 :         ExecuteSqlStatement(AH, q->data);
                               1481                 :              0 :         destroyPQExpBuffer(q);
                               1482                 :                :     }
                               1483                 :                :     else
 1413 tgl@sss.pgh.pa.us        1484                 :CBC         224 :         ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
                               1485                 :                : 
                               1486                 :                :     /*
                               1487                 :                :      * Disable synchronized scanning, to prevent unpredictable changes in row
                               1488                 :                :      * ordering across a dump and reload.
                               1489                 :                :      */
                               1490                 :            224 :     ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
                               1491                 :                : 
                               1492                 :                :     /*
                               1493                 :                :      * Disable timeouts if supported.
                               1494                 :                :      */
 3302                          1495                 :            224 :     ExecuteSqlStatement(AH, "SET statement_timeout = 0");
 4608                          1496         [ +  - ]:            224 :     if (AH->remoteVersion >= 90300)
                               1497                 :            224 :         ExecuteSqlStatement(AH, "SET lock_timeout = 0");
 3421                          1498         [ +  - ]:            224 :     if (AH->remoteVersion >= 90600)
                               1499                 :            224 :         ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
  620 akorotkov@postgresql     1500         [ +  - ]:            224 :     if (AH->remoteVersion >= 170000)
                               1501                 :            224 :         ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
                               1502                 :                : 
                               1503                 :                :     /*
                               1504                 :                :      * Quote all identifiers, if requested.
                               1505                 :                :      */
 1413 tgl@sss.pgh.pa.us        1506         [ +  + ]:            224 :     if (quote_all_identifiers)
 5011 rhaas@postgresql.org     1507                 :             34 :         ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
                               1508                 :                : 
                               1509                 :                :     /*
                               1510                 :                :      * Adjust row-security mode, if supported.
                               1511                 :                :      */
 3904 tgl@sss.pgh.pa.us        1512         [ +  - ]:            224 :     if (AH->remoteVersion >= 90500)
                               1513                 :                :     {
                               1514         [ -  + ]:            224 :         if (dopt->enable_row_security)
 3904 tgl@sss.pgh.pa.us        1515                 :UBC           0 :             ExecuteSqlStatement(AH, "SET row_security = on");
                               1516                 :                :         else
 3904 tgl@sss.pgh.pa.us        1517                 :CBC         224 :             ExecuteSqlStatement(AH, "SET row_security = off");
                               1518                 :                :     }
                               1519                 :                : 
                               1520                 :                :     /*
                               1521                 :                :      * For security reasons, we restrict the expansion of non-system views and
                               1522                 :                :      * access to foreign tables during the pg_dump process. This restriction
                               1523                 :                :      * is adjusted when dumping foreign table data.
                               1524                 :                :      */
  448 msawada@postgresql.o     1525                 :            224 :     set_restrict_relation_kind(AH, "view, foreign-table");
                               1526                 :                : 
                               1527                 :                :     /*
                               1528                 :                :      * Initialize prepared-query state to "nothing prepared".  We do this here
                               1529                 :                :      * so that a parallel dump worker will have its own state.
                               1530                 :                :      */
 1421 tgl@sss.pgh.pa.us        1531                 :            224 :     AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
                               1532                 :                : 
                               1533                 :                :     /*
                               1534                 :                :      * Start transaction-snapshot mode transaction to dump consistent data.
                               1535                 :                :      */
 4600 andrew@dunslane.net      1536                 :            224 :     ExecuteSqlStatement(AH, "BEGIN");
                               1537                 :                : 
                               1538                 :                :     /*
                               1539                 :                :      * To support the combination of serializable_deferrable with the jobs
                               1540                 :                :      * option we use REPEATABLE READ for the worker connections that are
                               1541                 :                :      * passed a snapshot.  As long as the snapshot is acquired in a
                               1542                 :                :      * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
                               1543                 :                :      * REPEATABLE READ transaction provides the appropriate integrity
                               1544                 :                :      * guarantees.  This is a kluge, but safe for back-patching.
                               1545                 :                :      */
 1413 tgl@sss.pgh.pa.us        1546   [ -  +  -  - ]:            224 :     if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
 1413 tgl@sss.pgh.pa.us        1547                 :UBC           0 :         ExecuteSqlStatement(AH,
                               1548                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1549                 :                :                             "SERIALIZABLE, READ ONLY, DEFERRABLE");
                               1550                 :                :     else
 4600 andrew@dunslane.net      1551                 :CBC         224 :         ExecuteSqlStatement(AH,
                               1552                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1553                 :                :                             "REPEATABLE READ, READ ONLY");
                               1554                 :                : 
                               1555                 :                :     /*
                               1556                 :                :      * If user specified a snapshot to use, select that.  In a parallel dump
                               1557                 :                :      * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
                               1558                 :                :      * is already set (if the server can handle it) and we should use that.
                               1559                 :                :      */
 3997 simon@2ndQuadrant.co     1560         [ -  + ]:            224 :     if (dumpsnapshot)
 3435 tgl@sss.pgh.pa.us        1561                 :UBC           0 :         AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
                               1562                 :                : 
 3997 simon@2ndQuadrant.co     1563         [ +  + ]:CBC         224 :     if (AH->sync_snapshot_id)
                               1564                 :                :     {
                               1565                 :             18 :         PQExpBuffer query = createPQExpBuffer();
                               1566                 :                : 
 2307 drowley@postgresql.o     1567                 :             18 :         appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
 3997 simon@2ndQuadrant.co     1568                 :             18 :         appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
                               1569                 :             18 :         ExecuteSqlStatement(AH, query->data);
                               1570                 :             18 :         destroyPQExpBuffer(query);
                               1571                 :                :     }
 1412 tgl@sss.pgh.pa.us        1572         [ +  + ]:            206 :     else if (AH->numWorkers > 1)
                               1573                 :                :     {
 2994 peter_e@gmx.net          1574   [ -  +  -  - ]:              9 :         if (AH->isStandby && AH->remoteVersion < 100000)
 1298 tgl@sss.pgh.pa.us        1575                 :UBC           0 :             pg_fatal("parallel dumps from standby servers are not supported by this server version");
 3997 simon@2ndQuadrant.co     1576                 :CBC           9 :         AH->sync_snapshot_id = get_synchronized_snapshot(AH);
                               1577                 :                :     }
 4600 andrew@dunslane.net      1578                 :            224 : }
                               1579                 :                : 
                               1580                 :                : /* Set up connection for a parallel worker process */
                               1581                 :                : static void
 3435 tgl@sss.pgh.pa.us        1582                 :             18 : setupDumpWorker(Archive *AH)
                               1583                 :                : {
                               1584                 :                :     /*
                               1585                 :                :      * We want to re-select all the same values the leader connection is
                               1586                 :                :      * using.  We'll have inherited directly-usable values in
                               1587                 :                :      * AH->sync_snapshot_id and AH->use_role, but we need to translate the
                               1588                 :                :      * inherited encoding value back to a string to pass to setup_connection.
                               1589                 :                :      */
                               1590                 :             18 :     setup_connection(AH,
                               1591                 :                :                      pg_encoding_to_char(AH->encoding),
                               1592                 :                :                      NULL,
                               1593                 :                :                      NULL);
 4600 andrew@dunslane.net      1594                 :             18 : }
                               1595                 :                : 
                               1596                 :                : static char *
                               1597                 :              9 : get_synchronized_snapshot(Archive *fout)
                               1598                 :                : {
 3435 tgl@sss.pgh.pa.us        1599                 :              9 :     char       *query = "SELECT pg_catalog.pg_export_snapshot()";
                               1600                 :                :     char       *result;
                               1601                 :                :     PGresult   *res;
                               1602                 :                : 
 4600 andrew@dunslane.net      1603                 :              9 :     res = ExecuteSqlQueryForSingleRow(fout, query);
 3435 tgl@sss.pgh.pa.us        1604                 :              9 :     result = pg_strdup(PQgetvalue(res, 0, 0));
 4600 andrew@dunslane.net      1605                 :              9 :     PQclear(res);
                               1606                 :                : 
                               1607                 :              9 :     return result;
                               1608                 :                : }
                               1609                 :                : 
                               1610                 :                : static ArchiveFormat
 5391 heikki.linnakangas@i     1611                 :            215 : parseArchiveFormat(const char *format, ArchiveMode *mode)
                               1612                 :                : {
                               1613                 :                :     ArchiveFormat archiveFormat;
                               1614                 :                : 
                               1615                 :            215 :     *mode = archModeWrite;
                               1616                 :                : 
                               1617   [ +  +  -  + ]:            215 :     if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
                               1618                 :                :     {
                               1619                 :                :         /* This is used by pg_dumpall, and is not documented */
                               1620                 :             43 :         archiveFormat = archNull;
                               1621                 :             43 :         *mode = archModeAppend;
                               1622                 :                :     }
                               1623         [ -  + ]:            172 :     else if (pg_strcasecmp(format, "c") == 0)
 5391 heikki.linnakangas@i     1624                 :UBC           0 :         archiveFormat = archCustom;
 5391 heikki.linnakangas@i     1625         [ +  + ]:CBC         172 :     else if (pg_strcasecmp(format, "custom") == 0)
                               1626                 :             45 :         archiveFormat = archCustom;
                               1627         [ -  + ]:            127 :     else if (pg_strcasecmp(format, "d") == 0)
 5391 heikki.linnakangas@i     1628                 :UBC           0 :         archiveFormat = archDirectory;
 5391 heikki.linnakangas@i     1629         [ +  + ]:CBC         127 :     else if (pg_strcasecmp(format, "directory") == 0)
                               1630                 :             11 :         archiveFormat = archDirectory;
                               1631         [ +  + ]:            116 :     else if (pg_strcasecmp(format, "p") == 0)
                               1632                 :            108 :         archiveFormat = archNull;
                               1633         [ +  + ]:              8 :     else if (pg_strcasecmp(format, "plain") == 0)
                               1634                 :              4 :         archiveFormat = archNull;
                               1635         [ -  + ]:              4 :     else if (pg_strcasecmp(format, "t") == 0)
 5391 heikki.linnakangas@i     1636                 :UBC           0 :         archiveFormat = archTar;
 5391 heikki.linnakangas@i     1637         [ +  + ]:CBC           4 :     else if (pg_strcasecmp(format, "tar") == 0)
                               1638                 :              3 :         archiveFormat = archTar;
                               1639                 :                :     else
 1298 tgl@sss.pgh.pa.us        1640                 :              1 :         pg_fatal("invalid output format \"%s\" specified", format);
 5391 heikki.linnakangas@i     1641                 :            214 :     return archiveFormat;
                               1642                 :                : }
                               1643                 :                : 
                               1644                 :                : /*
                               1645                 :                :  * Find the OIDs of all schemas matching the given list of patterns,
                               1646                 :                :  * and append them to the given OID list.
                               1647                 :                :  */
                               1648                 :                : static void
 5012 rhaas@postgresql.org     1649                 :            217 : expand_schema_name_patterns(Archive *fout,
                               1650                 :                :                             SimpleStringList *patterns,
                               1651                 :                :                             SimpleOidList *oids,
                               1652                 :                :                             bool strict_names)
                               1653                 :                : {
                               1654                 :                :     PQExpBuffer query;
                               1655                 :                :     PGresult   *res;
                               1656                 :                :     SimpleStringListCell *cell;
                               1657                 :                :     int         i;
                               1658                 :                : 
 6958 tgl@sss.pgh.pa.us        1659         [ +  + ]:            217 :     if (patterns->head == NULL)
                               1660                 :            196 :         return;                 /* nothing to do */
                               1661                 :                : 
                               1662                 :             21 :     query = createPQExpBuffer();
                               1663                 :                : 
                               1664                 :                :     /*
                               1665                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1666                 :                :      * duplicate entries in the OID list, but we don't care.
                               1667                 :                :      */
                               1668                 :                : 
                               1669         [ +  + ]:             36 :     for (cell = patterns->head; cell; cell = cell->next)
                               1670                 :                :     {
                               1671                 :                :         PQExpBufferData dbbuf;
                               1672                 :                :         int         dotcnt;
                               1673                 :                : 
 2307 drowley@postgresql.o     1674                 :             21 :         appendPQExpBufferStr(query,
                               1675                 :                :                              "SELECT oid FROM pg_catalog.pg_namespace n\n");
 1286 rhaas@postgresql.org     1676                 :             21 :         initPQExpBuffer(&dbbuf);
 5002                          1677                 :             21 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1678                 :                :                               false, NULL, "n.nspname", NULL, NULL, &dbbuf,
                               1679                 :                :                               &dotcnt);
 1286                          1680         [ +  + ]:             21 :         if (dotcnt > 1)
                               1681                 :              2 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1682                 :                :                      cell->val);
                               1683         [ +  + ]:             19 :         else if (dotcnt == 1)
                               1684                 :              3 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1685                 :             16 :         termPQExpBuffer(&dbbuf);
                               1686                 :                : 
 3696 teodor@sigaev.ru         1687                 :             16 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1688   [ +  +  +  - ]:             16 :         if (strict_names && PQntuples(res) == 0)
 1298 tgl@sss.pgh.pa.us        1689                 :              1 :             pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
                               1690                 :                : 
 3696 teodor@sigaev.ru         1691         [ +  + ]:             29 :         for (i = 0; i < PQntuples(res); i++)
                               1692                 :                :         {
                               1693                 :             14 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1694                 :                :         }
                               1695                 :                : 
                               1696                 :             15 :         PQclear(res);
                               1697                 :             15 :         resetPQExpBuffer(query);
                               1698                 :                :     }
                               1699                 :                : 
 6958 tgl@sss.pgh.pa.us        1700                 :             15 :     destroyPQExpBuffer(query);
                               1701                 :                : }
                               1702                 :                : 
                               1703                 :                : /*
                               1704                 :                :  * Find the OIDs of all extensions matching the given list of patterns,
                               1705                 :                :  * and append them to the given OID list.
                               1706                 :                :  */
                               1707                 :                : static void
 1671 michael@paquier.xyz      1708                 :            195 : expand_extension_name_patterns(Archive *fout,
                               1709                 :                :                                SimpleStringList *patterns,
                               1710                 :                :                                SimpleOidList *oids,
                               1711                 :                :                                bool strict_names)
                               1712                 :                : {
                               1713                 :                :     PQExpBuffer query;
                               1714                 :                :     PGresult   *res;
                               1715                 :                :     SimpleStringListCell *cell;
                               1716                 :                :     int         i;
                               1717                 :                : 
                               1718         [ +  + ]:            195 :     if (patterns->head == NULL)
                               1719                 :            188 :         return;                 /* nothing to do */
                               1720                 :                : 
                               1721                 :              7 :     query = createPQExpBuffer();
                               1722                 :                : 
                               1723                 :                :     /*
                               1724                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1725                 :                :      * duplicate entries in the OID list, but we don't care.
                               1726                 :                :      */
                               1727         [ +  + ]:             14 :     for (cell = patterns->head; cell; cell = cell->next)
                               1728                 :                :     {
                               1729                 :                :         int         dotcnt;
                               1730                 :                : 
                               1731                 :              7 :         appendPQExpBufferStr(query,
                               1732                 :                :                              "SELECT oid FROM pg_catalog.pg_extension e\n");
                               1733                 :              7 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1734                 :                :                               false, NULL, "e.extname", NULL, NULL, NULL,
                               1735                 :                :                               &dotcnt);
 1286 rhaas@postgresql.org     1736         [ -  + ]:              7 :         if (dotcnt > 0)
 1286 rhaas@postgresql.org     1737                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1738                 :                :                      cell->val);
                               1739                 :                : 
 1671 michael@paquier.xyz      1740                 :CBC           7 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1741   [ -  +  -  - ]:              7 :         if (strict_names && PQntuples(res) == 0)
 1298 tgl@sss.pgh.pa.us        1742                 :UBC           0 :             pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
                               1743                 :                : 
 1671 michael@paquier.xyz      1744         [ +  + ]:CBC          13 :         for (i = 0; i < PQntuples(res); i++)
                               1745                 :                :         {
                               1746                 :              6 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1747                 :                :         }
                               1748                 :                : 
                               1749                 :              7 :         PQclear(res);
                               1750                 :              7 :         resetPQExpBuffer(query);
                               1751                 :                :     }
                               1752                 :                : 
                               1753                 :              7 :     destroyPQExpBuffer(query);
                               1754                 :                : }
                               1755                 :                : 
                               1756                 :                : /*
                               1757                 :                :  * Find the OIDs of all foreign servers matching the given list of patterns,
                               1758                 :                :  * and append them to the given OID list.
                               1759                 :                :  */
                               1760                 :                : static void
 2042 alvherre@alvh.no-ip.     1761                 :            192 : expand_foreign_server_name_patterns(Archive *fout,
                               1762                 :                :                                     SimpleStringList *patterns,
                               1763                 :                :                                     SimpleOidList *oids)
                               1764                 :                : {
                               1765                 :                :     PQExpBuffer query;
                               1766                 :                :     PGresult   *res;
                               1767                 :                :     SimpleStringListCell *cell;
                               1768                 :                :     int         i;
                               1769                 :                : 
                               1770         [ +  + ]:            192 :     if (patterns->head == NULL)
                               1771                 :            189 :         return;                 /* nothing to do */
                               1772                 :                : 
                               1773                 :              3 :     query = createPQExpBuffer();
                               1774                 :                : 
                               1775                 :                :     /*
                               1776                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1777                 :                :      * duplicate entries in the OID list, but we don't care.
                               1778                 :                :      */
                               1779                 :                : 
                               1780         [ +  + ]:              5 :     for (cell = patterns->head; cell; cell = cell->next)
                               1781                 :                :     {
                               1782                 :                :         int         dotcnt;
                               1783                 :                : 
 1838 drowley@postgresql.o     1784                 :              3 :         appendPQExpBufferStr(query,
                               1785                 :                :                              "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
 2042 alvherre@alvh.no-ip.     1786                 :              3 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1787                 :                :                               false, NULL, "s.srvname", NULL, NULL, NULL,
                               1788                 :                :                               &dotcnt);
 1286 rhaas@postgresql.org     1789         [ -  + ]:              3 :         if (dotcnt > 0)
 1286 rhaas@postgresql.org     1790                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1791                 :                :                      cell->val);
                               1792                 :                : 
 2042 alvherre@alvh.no-ip.     1793                 :CBC           3 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1794         [ +  + ]:              3 :         if (PQntuples(res) == 0)
 1298 tgl@sss.pgh.pa.us        1795                 :              1 :             pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
                               1796                 :                : 
 2042 alvherre@alvh.no-ip.     1797         [ +  + ]:              4 :         for (i = 0; i < PQntuples(res); i++)
                               1798                 :              2 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1799                 :                : 
                               1800                 :              2 :         PQclear(res);
                               1801                 :              2 :         resetPQExpBuffer(query);
                               1802                 :                :     }
                               1803                 :                : 
                               1804                 :              2 :     destroyPQExpBuffer(query);
                               1805                 :                : }
                               1806                 :                : 
                               1807                 :                : /*
                               1808                 :                :  * Find the OIDs of all tables matching the given list of patterns,
                               1809                 :                :  * and append them to the given OID list. See also expand_dbname_patterns()
                               1810                 :                :  * in pg_dumpall.c
                               1811                 :                :  */
                               1812                 :                : static void
 5011 rhaas@postgresql.org     1813                 :           1161 : expand_table_name_patterns(Archive *fout,
                               1814                 :                :                            SimpleStringList *patterns, SimpleOidList *oids,
                               1815                 :                :                            bool strict_names, bool with_child_tables)
                               1816                 :                : {
                               1817                 :                :     PQExpBuffer query;
                               1818                 :                :     PGresult   *res;
                               1819                 :                :     SimpleStringListCell *cell;
                               1820                 :                :     int         i;
                               1821                 :                : 
 6958 tgl@sss.pgh.pa.us        1822         [ +  + ]:           1161 :     if (patterns->head == NULL)
                               1823                 :           1132 :         return;                 /* nothing to do */
                               1824                 :                : 
                               1825                 :             29 :     query = createPQExpBuffer();
                               1826                 :                : 
                               1827                 :                :     /*
                               1828                 :                :      * this might sometimes result in duplicate entries in the OID list, but
                               1829                 :                :      * we don't care.
                               1830                 :                :      */
                               1831                 :                : 
                               1832         [ +  + ]:             59 :     for (cell = patterns->head; cell; cell = cell->next)
                               1833                 :                :     {
                               1834                 :                :         PQExpBufferData dbbuf;
                               1835                 :                :         int         dotcnt;
                               1836                 :                : 
                               1837                 :                :         /*
                               1838                 :                :          * Query must remain ABSOLUTELY devoid of unqualified names.  This
                               1839                 :                :          * would be unnecessary given a pg_table_is_visible() variant taking a
                               1840                 :                :          * search_path argument.
                               1841                 :                :          *
                               1842                 :                :          * For with_child_tables, we start with the basic query's results and
                               1843                 :                :          * recursively search the inheritance tree to add child tables.
                               1844                 :                :          */
  958                          1845         [ +  + ]:             35 :         if (with_child_tables)
                               1846                 :                :         {
  192 drowley@postgresql.o     1847                 :              6 :             appendPQExpBufferStr(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
                               1848                 :                :         }
                               1849                 :                : 
 6958 tgl@sss.pgh.pa.us        1850                 :             35 :         appendPQExpBuffer(query,
                               1851                 :                :                           "SELECT c.oid"
                               1852                 :                :                           "\nFROM pg_catalog.pg_class c"
                               1853                 :                :                           "\n     LEFT JOIN pg_catalog.pg_namespace n"
                               1854                 :                :                           "\n     ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
                               1855                 :                :                           "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
                               1856                 :                :                           "\n    (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
                               1857                 :                :                           RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
                               1858                 :                :                           RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
                               1859                 :                :                           RELKIND_PARTITIONED_TABLE);
 1286 rhaas@postgresql.org     1860                 :             35 :         initPQExpBuffer(&dbbuf);
 5002                          1861                 :             35 :         processSQLNamePattern(GetConnection(fout), query, cell->val, true,
                               1862                 :                :                               false, "n.nspname", "c.relname", NULL,
                               1863                 :                :                               "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
                               1864                 :                :                               &dotcnt);
 1286                          1865         [ +  + ]:             35 :         if (dotcnt > 2)
                               1866                 :              1 :             pg_fatal("improper relation name (too many dotted names): %s",
                               1867                 :                :                      cell->val);
                               1868         [ +  + ]:             34 :         else if (dotcnt == 2)
                               1869                 :              2 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1870                 :             32 :         termPQExpBuffer(&dbbuf);
                               1871                 :                : 
  958 tgl@sss.pgh.pa.us        1872         [ +  + ]:             32 :         if (with_child_tables)
                               1873                 :                :         {
  192 drowley@postgresql.o     1874                 :              6 :             appendPQExpBufferStr(query, "UNION"
                               1875                 :                :                                  "\nSELECT i.inhrelid"
                               1876                 :                :                                  "\nFROM partition_tree p"
                               1877                 :                :                                  "\n     JOIN pg_catalog.pg_inherits i"
                               1878                 :                :                                  "\n     ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
                               1879                 :                :                                  "\n)"
                               1880                 :                :                                  "\nSELECT relid FROM partition_tree");
                               1881                 :                :         }
                               1882                 :                : 
 2800 noah@leadboat.com        1883                 :             32 :         ExecuteSqlStatement(fout, "RESET search_path");
 3696 teodor@sigaev.ru         1884                 :             32 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 2800 noah@leadboat.com        1885                 :             32 :         PQclear(ExecuteSqlQueryForSingleRow(fout,
                               1886                 :                :                                             ALWAYS_SECURE_SEARCH_PATH_SQL));
 3696 teodor@sigaev.ru         1887   [ +  +  +  + ]:             32 :         if (strict_names && PQntuples(res) == 0)
 1298 tgl@sss.pgh.pa.us        1888                 :              2 :             pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
                               1889                 :                : 
 3696 teodor@sigaev.ru         1890         [ +  + ]:             74 :         for (i = 0; i < PQntuples(res); i++)
                               1891                 :                :         {
                               1892                 :             44 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1893                 :                :         }
                               1894                 :                : 
                               1895                 :             30 :         PQclear(res);
                               1896                 :             30 :         resetPQExpBuffer(query);
                               1897                 :                :     }
                               1898                 :                : 
 6958 tgl@sss.pgh.pa.us        1899                 :             24 :     destroyPQExpBuffer(query);
                               1900                 :                : }
                               1901                 :                : 
                               1902                 :                : /*
                               1903                 :                :  * Verifies that the connected database name matches the given database name,
                               1904                 :                :  * and if not, dies with an error about the given pattern.
                               1905                 :                :  *
                               1906                 :                :  * The 'dbname' argument should be a literal name parsed from 'pattern'.
                               1907                 :                :  */
                               1908                 :                : static void
 1286 rhaas@postgresql.org     1909                 :              5 : prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
                               1910                 :                : {
                               1911                 :                :     const char *db;
                               1912                 :                : 
                               1913                 :              5 :     db = PQdb(conn);
                               1914         [ -  + ]:              5 :     if (db == NULL)
 1286 rhaas@postgresql.org     1915                 :UBC           0 :         pg_fatal("You are currently not connected to a database.");
                               1916                 :                : 
 1286 rhaas@postgresql.org     1917         [ +  - ]:CBC           5 :     if (strcmp(db, dbname) != 0)
                               1918                 :              5 :         pg_fatal("cross-database references are not implemented: %s",
                               1919                 :                :                  pattern);
 1286 rhaas@postgresql.org     1920                 :UBC           0 : }
                               1921                 :                : 
                               1922                 :                : /*
                               1923                 :                :  * checkExtensionMembership
                               1924                 :                :  *      Determine whether object is an extension member, and if so,
                               1925                 :                :  *      record an appropriate dependency and set the object's dump flag.
                               1926                 :                :  *
                               1927                 :                :  * It's important to call this for each object that could be an extension
                               1928                 :                :  * member.  Generally, we integrate this with determining the object's
                               1929                 :                :  * to-be-dumped-ness, since extension membership overrides other rules for that.
                               1930                 :                :  *
                               1931                 :                :  * Returns true if object is an extension member, else false.
                               1932                 :                :  */
                               1933                 :                : static bool
 3491 sfrost@snowman.net       1934                 :CBC      728421 : checkExtensionMembership(DumpableObject *dobj, Archive *fout)
                               1935                 :                : {
 3575 tgl@sss.pgh.pa.us        1936                 :         728421 :     ExtensionInfo *ext = findOwningExtension(dobj->catId);
                               1937                 :                : 
                               1938         [ +  + ]:         728421 :     if (ext == NULL)
                               1939                 :         727619 :         return false;
                               1940                 :                : 
                               1941                 :            802 :     dobj->ext_member = true;
                               1942                 :                : 
                               1943                 :                :     /* Record dependency so that getDependencies needn't deal with that */
                               1944                 :            802 :     addObjectDependency(dobj, ext->dobj.dumpId);
                               1945                 :                : 
                               1946                 :                :     /*
                               1947                 :                :      * In 9.6 and above, mark the member object to have any non-initial ACLs
                               1948                 :                :      * dumped.  (Any initial ACLs will be removed later, using data from
                               1949                 :                :      * pg_init_privs, so that we'll dump only the delta from the extension's
                               1950                 :                :      * initial setup.)
                               1951                 :                :      *
                               1952                 :                :      * Prior to 9.6, we do not include any extension member components.
                               1953                 :                :      *
                               1954                 :                :      * In binary upgrades, we still dump all components of the members
                               1955                 :                :      * individually, since the idea is to exactly reproduce the database
                               1956                 :                :      * contents rather than replace the extension contents with something
                               1957                 :                :      * different.
                               1958                 :                :      *
                               1959                 :                :      * Note: it might be interesting someday to implement storage and delta
                               1960                 :                :      * dumping of extension members' RLS policies and/or security labels.
                               1961                 :                :      * However there is a pitfall for RLS policies: trying to dump them
                               1962                 :                :      * requires getting a lock on their tables, and the calling user might not
                               1963                 :                :      * have privileges for that.  We need no lock to examine a table's ACLs,
                               1964                 :                :      * so the current feature doesn't have a problem of that sort.
                               1965                 :                :      */
 3461 sfrost@snowman.net       1966         [ +  + ]:            802 :     if (fout->dopt->binary_upgrade)
 3575 tgl@sss.pgh.pa.us        1967                 :            169 :         dobj->dump = ext->dobj.dump;
                               1968                 :                :     else
                               1969                 :                :     {
 3461 sfrost@snowman.net       1970         [ -  + ]:            633 :         if (fout->remoteVersion < 90600)
 3461 sfrost@snowman.net       1971                 :UBC           0 :             dobj->dump = DUMP_COMPONENT_NONE;
                               1972                 :                :         else
  714 tgl@sss.pgh.pa.us        1973                 :CBC         633 :             dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
                               1974                 :                :     }
                               1975                 :                : 
 3575                          1976                 :            802 :     return true;
                               1977                 :                : }
                               1978                 :                : 
                               1979                 :                : /*
                               1980                 :                :  * selectDumpableNamespace: policy-setting subroutine
                               1981                 :                :  *      Mark a namespace as to be dumped or not
                               1982                 :                :  */
                               1983                 :                : static void
 3491 sfrost@snowman.net       1984                 :           1430 : selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
                               1985                 :                : {
                               1986                 :                :     /*
                               1987                 :                :      * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
                               1988                 :                :      * and (for --clean) a DROP SCHEMA statement.  (In the absence of
                               1989                 :                :      * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
                               1990                 :                :      */
 1582 noah@leadboat.com        1991                 :           1430 :     nsinfo->create = true;
                               1992                 :                : 
                               1993                 :                :     /*
                               1994                 :                :      * If specific tables are being dumped, do not dump any complete
                               1995                 :                :      * namespaces. If specific namespaces are being dumped, dump just those
                               1996                 :                :      * namespaces. Otherwise, dump all non-system namespaces.
                               1997                 :                :      */
 6958 tgl@sss.pgh.pa.us        1998         [ +  + ]:           1430 :     if (table_include_oids.head != NULL)
 3491 sfrost@snowman.net       1999                 :             50 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
 6958 tgl@sss.pgh.pa.us        2000         [ +  + ]:           1380 :     else if (schema_include_oids.head != NULL)
 3491 sfrost@snowman.net       2001                 :            187 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
                               2002                 :            187 :             simple_oid_list_member(&schema_include_oids,
                               2003                 :                :                                    nsinfo->dobj.catId.oid) ?
                               2004         [ +  + ]:            187 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2005         [ +  - ]:           1193 :     else if (fout->remoteVersion >= 90600 &&
 3336 tgl@sss.pgh.pa.us        2006         [ +  + ]:           1193 :              strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
                               2007                 :                :     {
                               2008                 :                :         /*
                               2009                 :                :          * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
                               2010                 :                :          * they are interesting (and not the original ACLs which were set at
                               2011                 :                :          * initdb time, see pg_init_privs).
                               2012                 :                :          */
 3491 sfrost@snowman.net       2013                 :            168 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
                               2014                 :                :     }
 6958 tgl@sss.pgh.pa.us        2015         [ +  + ]:           1025 :     else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
                               2016         [ +  + ]:            509 :              strcmp(nsinfo->dobj.name, "information_schema") == 0)
                               2017                 :                :     {
                               2018                 :                :         /* Other system schemas don't get dumped */
 3491 sfrost@snowman.net       2019                 :            684 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2020                 :                :     }
 2832 tgl@sss.pgh.pa.us        2021         [ +  + ]:            341 :     else if (strcmp(nsinfo->dobj.name, "public") == 0)
                               2022                 :                :     {
                               2023                 :                :         /*
                               2024                 :                :          * The public schema is a strange beast that sits in a sort of
                               2025                 :                :          * no-mans-land between being a system object and a user object.
                               2026                 :                :          * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
                               2027                 :                :          * a comment and an indication of ownership.  If the owner is the
                               2028                 :                :          * default, omit that superfluous DUMP_COMPONENT_DEFINITION.  Before
                               2029                 :                :          * v15, the default owner was BOOTSTRAP_SUPERUSERID.
                               2030                 :                :          */
 1582 noah@leadboat.com        2031                 :            164 :         nsinfo->create = false;
                               2032                 :            164 :         nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
 1509                          2033         [ +  + ]:            164 :         if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
 1582                          2034                 :            122 :             nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
 2832 tgl@sss.pgh.pa.us        2035                 :            164 :         nsinfo->dobj.dump_contains = DUMP_COMPONENT_ALL;
                               2036                 :                : 
                               2037                 :                :         /*
                               2038                 :                :          * Also, make like it has a comment even if it doesn't; this is so
                               2039                 :                :          * that we'll emit a command to drop the comment, if appropriate.
                               2040                 :                :          * (Without this, we'd not call dumpCommentExtended for it.)
                               2041                 :                :          */
 1421                          2042                 :            164 :         nsinfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                               2043                 :                :     }
                               2044                 :                :     else
 3491 sfrost@snowman.net       2045                 :            177 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
                               2046                 :                : 
                               2047                 :                :     /*
                               2048                 :                :      * In any case, a namespace can be excluded by an exclusion switch
                               2049                 :                :      */
                               2050   [ +  +  +  + ]:           1950 :     if (nsinfo->dobj.dump_contains &&
 6958 tgl@sss.pgh.pa.us        2051                 :            520 :         simple_oid_list_member(&schema_exclude_oids,
                               2052                 :                :                                nsinfo->dobj.catId.oid))
 3491 sfrost@snowman.net       2053                 :              3 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2054                 :                : 
                               2055                 :                :     /*
                               2056                 :                :      * If the schema belongs to an extension, allow extension membership to
                               2057                 :                :      * override the dump decision for the schema itself.  However, this does
                               2058                 :                :      * not change dump_contains, so this won't change what we do with objects
                               2059                 :                :      * within the schema.  (If they belong to the extension, they'll get
                               2060                 :                :      * suppressed by it, otherwise not.)
                               2061                 :                :      */
 3336 tgl@sss.pgh.pa.us        2062                 :           1430 :     (void) checkExtensionMembership(&nsinfo->dobj, fout);
 6958                          2063                 :           1430 : }
                               2064                 :                : 
                               2065                 :                : /*
                               2066                 :                :  * selectDumpableTable: policy-setting subroutine
                               2067                 :                :  *      Mark a table as to be dumped or not
                               2068                 :                :  */
                               2069                 :                : static void
 3491 sfrost@snowman.net       2070                 :          49729 : selectDumpableTable(TableInfo *tbinfo, Archive *fout)
                               2071                 :                : {
                               2072         [ +  + ]:          49729 :     if (checkExtensionMembership(&tbinfo->dobj, fout))
 3575 tgl@sss.pgh.pa.us        2073                 :            225 :         return;                 /* extension membership overrides all else */
                               2074                 :                : 
                               2075                 :                :     /*
                               2076                 :                :      * If specific tables are being dumped, dump just those tables; else, dump
                               2077                 :                :      * according to the parent namespace's dump flag.
                               2078                 :                :      */
 6958                          2079         [ +  + ]:          49504 :     if (table_include_oids.head != NULL)
                               2080                 :           5182 :         tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
                               2081                 :                :                                                    tbinfo->dobj.catId.oid) ?
 3491 sfrost@snowman.net       2082         [ +  + ]:           2591 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2083                 :                :     else
                               2084                 :          46913 :         tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
                               2085                 :                : 
                               2086                 :                :     /*
                               2087                 :                :      * In any case, a table can be excluded by an exclusion switch
                               2088                 :                :      */
 6958 tgl@sss.pgh.pa.us        2089   [ +  +  +  + ]:          81006 :     if (tbinfo->dobj.dump &&
                               2090                 :          31502 :         simple_oid_list_member(&table_exclude_oids,
                               2091                 :                :                                tbinfo->dobj.catId.oid))
 3491 sfrost@snowman.net       2092                 :             12 :         tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2093                 :                : }
                               2094                 :                : 
                               2095                 :                : /*
                               2096                 :                :  * selectDumpableType: policy-setting subroutine
                               2097                 :                :  *      Mark a type as to be dumped or not
                               2098                 :                :  *
                               2099                 :                :  * If it's a table's rowtype or an autogenerated array type, we also apply a
                               2100                 :                :  * special type code to facilitate sorting into the desired order.  (We don't
                               2101                 :                :  * want to consider those to be ordinary types because that would bring tables
                               2102                 :                :  * up into the datatype part of the dump order.)  We still set the object's
                               2103                 :                :  * dump flag; that's not going to cause the dummy type to be dumped, but we
                               2104                 :                :  * need it so that casts involving such types will be dumped correctly -- see
                               2105                 :                :  * dumpCast.  This means the flag should be set the same as for the underlying
                               2106                 :                :  * object (the table or base type).
                               2107                 :                :  */
                               2108                 :                : static void
                               2109                 :         136675 : selectDumpableType(TypeInfo *tyinfo, Archive *fout)
                               2110                 :                : {
                               2111                 :                :     /* skip complex types, except for standalone composite types */
 5787 bruce@momjian.us         2112         [ +  + ]:         136675 :     if (OidIsValid(tyinfo->typrelid) &&
                               2113         [ +  + ]:          49004 :         tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
                               2114                 :                :     {
 5123 tgl@sss.pgh.pa.us        2115                 :          48822 :         TableInfo  *tytable = findTableByOid(tyinfo->typrelid);
                               2116                 :                : 
 5787 bruce@momjian.us         2117                 :          48822 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
 5123 tgl@sss.pgh.pa.us        2118         [ +  - ]:          48822 :         if (tytable != NULL)
                               2119                 :          48822 :             tyinfo->dobj.dump = tytable->dobj.dump;
                               2120                 :                :         else
 3491 sfrost@snowman.net       2121                 :UBC           0 :             tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
 5123 tgl@sss.pgh.pa.us        2122                 :CBC       48822 :         return;
                               2123                 :                :     }
                               2124                 :                : 
                               2125                 :                :     /* skip auto-generated array and multirange types */
 1772 akorotkov@postgresql     2126   [ +  +  +  + ]:          87853 :     if (tyinfo->isArray || tyinfo->isMultirange)
                               2127                 :                :     {
 5787 bruce@momjian.us         2128                 :          66837 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
                               2129                 :                : 
                               2130                 :                :         /*
                               2131                 :                :          * Fall through to set the dump flag; we assume that the subsequent
                               2132                 :                :          * rules will do the same thing as they would for the array's base
                               2133                 :                :          * type or multirange's range type.  (We cannot reliably look up the
                               2134                 :                :          * base type here, since getTypes may not have processed it yet.)
                               2135                 :                :          */
                               2136                 :                :     }
                               2137                 :                : 
 3491 sfrost@snowman.net       2138         [ +  + ]:          87853 :     if (checkExtensionMembership(&tyinfo->dobj, fout))
 3575 tgl@sss.pgh.pa.us        2139                 :            150 :         return;                 /* extension membership overrides all else */
                               2140                 :                : 
                               2141                 :                :     /* Dump based on if the contents of the namespace are being dumped */
 3491 sfrost@snowman.net       2142                 :          87703 :     tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
                               2143                 :                : }
                               2144                 :                : 
                               2145                 :                : /*
                               2146                 :                :  * selectDumpableDefaultACL: policy-setting subroutine
                               2147                 :                :  *      Mark a default ACL as to be dumped or not
                               2148                 :                :  *
                               2149                 :                :  * For per-schema default ACLs, dump if the schema is to be dumped.
                               2150                 :                :  * Otherwise dump if we are dumping "everything".  Note that dumpSchema
                               2151                 :                :  * and aclsSkip are checked separately.
                               2152                 :                :  */
                               2153                 :                : static void
 3575 tgl@sss.pgh.pa.us        2154                 :            194 : selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
                               2155                 :                : {
                               2156                 :                :     /* Default ACLs can't be extension members */
                               2157                 :                : 
 5866                          2158         [ +  + ]:            194 :     if (dinfo->dobj.namespace)
                               2159                 :                :         /* default ACLs are considered part of the namespace */
 3461 sfrost@snowman.net       2160                 :             90 :         dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
                               2161                 :                :     else
 3491                          2162                 :            104 :         dinfo->dobj.dump = dopt->include_everything ?
                               2163         [ +  + ]:            104 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
 5866 tgl@sss.pgh.pa.us        2164                 :            194 : }
                               2165                 :                : 
                               2166                 :                : /*
                               2167                 :                :  * selectDumpableCast: policy-setting subroutine
                               2168                 :                :  *      Mark a cast as to be dumped or not
                               2169                 :                :  *
                               2170                 :                :  * Casts do not belong to any particular namespace (since they haven't got
                               2171                 :                :  * names), nor do they have identifiable owners.  To distinguish user-defined
                               2172                 :                :  * casts from built-in ones, we must resort to checking whether the cast's
                               2173                 :                :  * OID is in the range reserved for initdb.
                               2174                 :                :  */
                               2175                 :                : static void
 3491 sfrost@snowman.net       2176                 :          44691 : selectDumpableCast(CastInfo *cast, Archive *fout)
                               2177                 :                : {
                               2178         [ -  + ]:          44691 :     if (checkExtensionMembership(&cast->dobj, fout))
 3575 tgl@sss.pgh.pa.us        2179                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2180                 :                : 
                               2181                 :                :     /*
                               2182                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
                               2183                 :                :      * support ACLs currently.
                               2184                 :                :      */
 3232 sfrost@snowman.net       2185         [ +  + ]:CBC       44691 :     if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3491                          2186                 :          44604 :         cast->dobj.dump = DUMP_COMPONENT_NONE;
                               2187                 :                :     else
                               2188                 :             87 :         cast->dobj.dump = fout->dopt->include_everything ?
                               2189         [ +  + ]:             87 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2190                 :                : }
                               2191                 :                : 
                               2192                 :                : /*
                               2193                 :                :  * selectDumpableProcLang: policy-setting subroutine
                               2194                 :                :  *      Mark a procedural language as to be dumped or not
                               2195                 :                :  *
                               2196                 :                :  * Procedural languages do not belong to any particular namespace.  To
                               2197                 :                :  * identify built-in languages, we must resort to checking whether the
                               2198                 :                :  * language's OID is in the range reserved for initdb.
                               2199                 :                :  */
                               2200                 :                : static void
                               2201                 :            234 : selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
                               2202                 :                : {
                               2203         [ +  + ]:            234 :     if (checkExtensionMembership(&plang->dobj, fout))
 3575 tgl@sss.pgh.pa.us        2204                 :            189 :         return;                 /* extension membership overrides all else */
                               2205                 :                : 
                               2206                 :                :     /*
                               2207                 :                :      * Only include procedural languages when we are dumping everything.
                               2208                 :                :      *
                               2209                 :                :      * For from-initdb procedural languages, only include ACLs, as we do for
                               2210                 :                :      * the pg_catalog namespace.  We need this because procedural languages do
                               2211                 :                :      * not live in any namespace.
                               2212                 :                :      */
 3461 sfrost@snowman.net       2213         [ +  + ]:             45 :     if (!fout->dopt->include_everything)
 3491                          2214                 :              8 :         plang->dobj.dump = DUMP_COMPONENT_NONE;
                               2215                 :                :     else
                               2216                 :                :     {
 3232                          2217         [ -  + ]:             37 :         if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3461 sfrost@snowman.net       2218                 :UBC           0 :             plang->dobj.dump = fout->remoteVersion < 90600 ?
                               2219         [ #  # ]:              0 :                 DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL;
                               2220                 :                :         else
 3461 sfrost@snowman.net       2221                 :CBC          37 :             plang->dobj.dump = DUMP_COMPONENT_ALL;
                               2222                 :                :     }
                               2223                 :                : }
                               2224                 :                : 
                               2225                 :                : /*
                               2226                 :                :  * selectDumpableAccessMethod: policy-setting subroutine
                               2227                 :                :  *      Mark an access method as to be dumped or not
                               2228                 :                :  *
                               2229                 :                :  * Access methods do not belong to any particular namespace.  To identify
                               2230                 :                :  * built-in access methods, we must resort to checking whether the
                               2231                 :                :  * method's OID is in the range reserved for initdb.
                               2232                 :                :  */
                               2233                 :                : static void
 3491                          2234                 :           1445 : selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
                               2235                 :                : {
                               2236                 :                :     /* see getAccessMethods() comment about v9.6. */
   88 noah@leadboat.com        2237         [ -  + ]:           1445 :     if (fout->remoteVersion < 90600)
                               2238                 :                :     {
   88 noah@leadboat.com        2239                 :UBC           0 :         method->dobj.dump = DUMP_COMPONENT_NONE;
                               2240                 :              0 :         return;
                               2241                 :                :     }
                               2242                 :                : 
 3491 sfrost@snowman.net       2243         [ +  + ]:CBC        1445 :     if (checkExtensionMembership(&method->dobj, fout))
 3505 alvherre@alvh.no-ip.     2244                 :             25 :         return;                 /* extension membership overrides all else */
                               2245                 :                : 
                               2246                 :                :     /*
                               2247                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
                               2248                 :                :      * they do not support ACLs currently.
                               2249                 :                :      */
 3232 sfrost@snowman.net       2250         [ +  + ]:           1420 :     if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3491                          2251                 :           1323 :         method->dobj.dump = DUMP_COMPONENT_NONE;
                               2252                 :                :     else
                               2253                 :             97 :         method->dobj.dump = fout->dopt->include_everything ?
                               2254         [ +  + ]:             97 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2255                 :                : }
                               2256                 :                : 
                               2257                 :                : /*
                               2258                 :                :  * selectDumpableExtension: policy-setting subroutine
                               2259                 :                :  *      Mark an extension as to be dumped or not
                               2260                 :                :  *
                               2261                 :                :  * Built-in extensions should be skipped except for checking ACLs, since we
                               2262                 :                :  * assume those will already be installed in the target database.  We identify
                               2263                 :                :  * such extensions by their having OIDs in the range reserved for initdb.
                               2264                 :                :  * We dump all user-added extensions by default.  No extensions are dumped
                               2265                 :                :  * if include_everything is false (i.e., a --schema or --table switch was
                               2266                 :                :  * given), except if --extension specifies a list of extensions to dump.
                               2267                 :                :  */
                               2268                 :                : static void
 3575 tgl@sss.pgh.pa.us        2269                 :            220 : selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
                               2270                 :                : {
                               2271                 :                :     /*
                               2272                 :                :      * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
                               2273                 :                :      * change permissions on their member objects, if they wish to, and have
                               2274                 :                :      * those changes preserved.
                               2275                 :                :      */
 2832                          2276         [ +  + ]:            220 :     if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3461 sfrost@snowman.net       2277                 :            190 :         extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
                               2278                 :                :     else
                               2279                 :                :     {
                               2280                 :                :         /* check if there is a list of extensions to dump */
 1671 michael@paquier.xyz      2281         [ +  + ]:             30 :         if (extension_include_oids.head != NULL)
                               2282                 :              4 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2283                 :              4 :                 simple_oid_list_member(&extension_include_oids,
                               2284                 :                :                                        extinfo->dobj.catId.oid) ?
                               2285         [ +  + ]:              4 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2286                 :                :         else
                               2287                 :             26 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2288                 :             26 :                 dopt->include_everything ?
                               2289         [ +  + ]:             26 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2290                 :                : 
                               2291                 :                :         /* check that the extension is not explicitly excluded */
  586 dean.a.rasheed@gmail     2292   [ +  +  +  + ]:             56 :         if (extinfo->dobj.dump &&
                               2293                 :             26 :             simple_oid_list_member(&extension_exclude_oids,
                               2294                 :                :                                    extinfo->dobj.catId.oid))
                               2295                 :              2 :             extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
                               2296                 :                :     }
 5351 tgl@sss.pgh.pa.us        2297                 :            220 : }
                               2298                 :                : 
                               2299                 :                : /*
                               2300                 :                :  * selectDumpablePublicationObject: policy-setting subroutine
                               2301                 :                :  *      Mark a publication object as to be dumped or not
                               2302                 :                :  *
                               2303                 :                :  * A publication can have schemas and tables which have schemas, but those are
                               2304                 :                :  * ignored in decision making, because publications are only dumped when we are
                               2305                 :                :  * dumping everything.
                               2306                 :                :  */
                               2307                 :                : static void
 1461 akapila@postgresql.o     2308                 :            475 : selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
                               2309                 :                : {
 3142 peter_e@gmx.net          2310         [ -  + ]:            475 :     if (checkExtensionMembership(dobj, fout))
 3142 peter_e@gmx.net          2311                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2312                 :                : 
 3142 peter_e@gmx.net          2313                 :CBC         475 :     dobj->dump = fout->dopt->include_everything ?
                               2314         [ +  + ]:            475 :         DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2315                 :                : }
                               2316                 :                : 
                               2317                 :                : /*
                               2318                 :                :  * selectDumpableStatisticsObject: policy-setting subroutine
                               2319                 :                :  *      Mark an extended statistics object as to be dumped or not
                               2320                 :                :  *
                               2321                 :                :  * We dump an extended statistics object if the schema it's in and the table
                               2322                 :                :  * it's for are being dumped.  (This'll need more thought if statistics
                               2323                 :                :  * objects ever support cross-table stats.)
                               2324                 :                :  */
                               2325                 :                : static void
  668 tgl@sss.pgh.pa.us        2326                 :            163 : selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
                               2327                 :                : {
                               2328         [ -  + ]:            163 :     if (checkExtensionMembership(&sobj->dobj, fout))
  668 tgl@sss.pgh.pa.us        2329                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2330                 :                : 
  668 tgl@sss.pgh.pa.us        2331                 :CBC         163 :     sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
                               2332         [ +  - ]:            163 :     if (sobj->stattable == NULL ||
                               2333         [ +  + ]:            163 :         !(sobj->stattable->dobj.dump & DUMP_COMPONENT_DEFINITION))
                               2334                 :             28 :         sobj->dobj.dump = DUMP_COMPONENT_NONE;
                               2335                 :                : }
                               2336                 :                : 
                               2337                 :                : /*
                               2338                 :                :  * selectDumpableObject: policy-setting subroutine
                               2339                 :                :  *      Mark a generic dumpable object as to be dumped or not
                               2340                 :                :  *
                               2341                 :                :  * Use this only for object types without a special-case routine above.
                               2342                 :                :  */
                               2343                 :                : static void
 3491 sfrost@snowman.net       2344                 :         542401 : selectDumpableObject(DumpableObject *dobj, Archive *fout)
                               2345                 :                : {
                               2346         [ +  + ]:         542401 :     if (checkExtensionMembership(dobj, fout))
 3575 tgl@sss.pgh.pa.us        2347                 :            188 :         return;                 /* extension membership overrides all else */
                               2348                 :                : 
                               2349                 :                :     /*
                               2350                 :                :      * Default policy is to dump if parent namespace is dumpable, or for
                               2351                 :                :      * non-namespace-associated items, dump if we're dumping "everything".
                               2352                 :                :      */
 7179                          2353         [ +  + ]:         542213 :     if (dobj->namespace)
 3491 sfrost@snowman.net       2354                 :         541482 :         dobj->dump = dobj->namespace->dobj.dump_contains;
                               2355                 :                :     else
                               2356                 :            731 :         dobj->dump = fout->dopt->include_everything ?
                               2357         [ +  + ]:            731 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2358                 :                : }
                               2359                 :                : 
                               2360                 :                : /*
                               2361                 :                :  *  Dump a table's contents for loading using the COPY command
                               2362                 :                :  *  - this routine is called by the Archiver when it wants the table
                               2363                 :                :  *    to be dumped.
                               2364                 :                :  */
                               2365                 :                : static int
 1720 peter@eisentraut.org     2366                 :           4063 : dumpTableData_copy(Archive *fout, const void *dcontext)
                               2367                 :                : {
 7996 tgl@sss.pgh.pa.us        2368                 :           4063 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2369                 :           4063 :     TableInfo  *tbinfo = tdinfo->tdtable;
 7908                          2370                 :           4063 :     const char *classname = tbinfo->dobj.name;
 8571                          2371                 :           4063 :     PQExpBuffer q = createPQExpBuffer();
                               2372                 :                : 
                               2373                 :                :     /*
                               2374                 :                :      * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
                               2375                 :                :      * which uses it already.
                               2376                 :                :      */
 4600 andrew@dunslane.net      2377                 :           4063 :     PQExpBuffer clistBuf = createPQExpBuffer();
 5002 rhaas@postgresql.org     2378                 :           4063 :     PGconn     *conn = GetConnection(fout);
                               2379                 :                :     PGresult   *res;
                               2380                 :                :     int         ret;
                               2381                 :                :     char       *copybuf;
                               2382                 :                :     const char *column_list;
                               2383                 :                : 
 2401 peter@eisentraut.org     2384                 :           4063 :     pg_log_info("dumping contents of table \"%s.%s\"",
                               2385                 :                :                 tbinfo->dobj.namespace->dobj.name, classname);
                               2386                 :                : 
                               2387                 :                :     /*
                               2388                 :                :      * Specify the column list explicitly so that we have no possibility of
                               2389                 :                :      * retrieving data in the wrong column order.  (The default column
                               2390                 :                :      * ordering of COPY will not be what we want in certain corner cases
                               2391                 :                :      * involving ADD COLUMN and inheritance.)
                               2392                 :                :      */
 3302 tgl@sss.pgh.pa.us        2393                 :           4063 :     column_list = fmtCopyColumnList(tbinfo, clistBuf);
                               2394                 :                : 
                               2395                 :                :     /*
                               2396                 :                :      * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
                               2397                 :                :      * a filter condition was specified.  For other cases a simple COPY
                               2398                 :                :      * suffices.
                               2399                 :                :      */
 2042 alvherre@alvh.no-ip.     2400   [ +  +  +  + ]:           4063 :     if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                               2401                 :                :     {
                               2402                 :                :         /* Temporary allows to access to foreign tables to dump data */
  448 msawada@postgresql.o     2403         [ +  + ]:             73 :         if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                               2404                 :              1 :             set_restrict_relation_kind(fout, "view");
                               2405                 :                : 
 5375 tgl@sss.pgh.pa.us        2406                 :             73 :         appendPQExpBufferStr(q, "COPY (SELECT ");
                               2407                 :                :         /* klugery to get rid of parens in column list */
                               2408         [ +  - ]:             73 :         if (strlen(column_list) > 2)
                               2409                 :                :         {
                               2410                 :             73 :             appendPQExpBufferStr(q, column_list + 1);
                               2411                 :             73 :             q->data[q->len - 1] = ' ';
                               2412                 :                :         }
                               2413                 :                :         else
 5375 tgl@sss.pgh.pa.us        2414                 :UBC           0 :             appendPQExpBufferStr(q, "* ");
                               2415                 :                : 
 5375 tgl@sss.pgh.pa.us        2416                 :CBC         146 :         appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
 2800                          2417                 :             73 :                           fmtQualifiedDumpable(tbinfo),
 2042 alvherre@alvh.no-ip.     2418         [ +  + ]:             73 :                           tdinfo->filtercond ? tdinfo->filtercond : "");
                               2419                 :                :     }
                               2420                 :                :     else
                               2421                 :                :     {
 8502 bruce@momjian.us         2422                 :           3990 :         appendPQExpBuffer(q, "COPY %s %s TO stdout;",
 2800 tgl@sss.pgh.pa.us        2423                 :           3990 :                           fmtQualifiedDumpable(tbinfo),
                               2424                 :                :                           column_list);
                               2425                 :                :     }
 5011 rhaas@postgresql.org     2426                 :           4063 :     res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
 7178 tgl@sss.pgh.pa.us        2427                 :           4062 :     PQclear(res);
 4600 andrew@dunslane.net      2428                 :           4062 :     destroyPQExpBuffer(clistBuf);
                               2429                 :                : 
                               2430                 :                :     for (;;)
                               2431                 :                :     {
 5002 rhaas@postgresql.org     2432                 :        1812308 :         ret = PQgetCopyData(conn, &copybuf, 0);
                               2433                 :                : 
 7178 tgl@sss.pgh.pa.us        2434         [ +  + ]:        1812308 :         if (ret < 0)
                               2435                 :           4062 :             break;              /* done or error */
                               2436                 :                : 
                               2437         [ +  - ]:        1808246 :         if (copybuf)
                               2438                 :                :         {
                               2439                 :        1808246 :             WriteData(fout, copybuf, ret);
                               2440                 :        1808246 :             PQfreemem(copybuf);
                               2441                 :                :         }
                               2442                 :                : 
                               2443                 :                :         /* ----------
                               2444                 :                :          * THROTTLE:
                               2445                 :                :          *
                               2446                 :                :          * There was considerable discussion in late July, 2000 regarding
                               2447                 :                :          * slowing down pg_dump when backing up large tables. Users with both
                               2448                 :                :          * slow & fast (multi-processor) machines experienced performance
                               2449                 :                :          * degradation when doing a backup.
                               2450                 :                :          *
                               2451                 :                :          * Initial attempts based on sleeping for a number of ms for each ms
                               2452                 :                :          * of work were deemed too complex, then a simple 'sleep in each loop'
                               2453                 :                :          * implementation was suggested. The latter failed because the loop
                               2454                 :                :          * was too tight. Finally, the following was implemented:
                               2455                 :                :          *
                               2456                 :                :          * If throttle is non-zero, then
                               2457                 :                :          *      See how long since the last sleep.
                               2458                 :                :          *      Work out how long to sleep (based on ratio).
                               2459                 :                :          *      If sleep is more than 100ms, then
                               2460                 :                :          *          sleep
                               2461                 :                :          *          reset timer
                               2462                 :                :          *      EndIf
                               2463                 :                :          * EndIf
                               2464                 :                :          *
                               2465                 :                :          * where the throttle value was the number of ms to sleep per ms of
                               2466                 :                :          * work. The calculation was done in each loop.
                               2467                 :                :          *
                               2468                 :                :          * Most of the hard work is done in the backend, and this solution
                               2469                 :                :          * still did not work particularly well: on slow machines, the ratio
                               2470                 :                :          * was 50:1, and on medium paced machines, 1:1, and on fast
                               2471                 :                :          * multi-processor machines, it had little or no effect, for reasons
                               2472                 :                :          * that were unclear.
                               2473                 :                :          *
                               2474                 :                :          * Further discussion ensued, and the proposal was dropped.
                               2475                 :                :          *
                               2476                 :                :          * For those people who want this feature, it can be implemented using
                               2477                 :                :          * gettimeofday in each loop, calculating the time since last sleep,
                               2478                 :                :          * multiplying that by the sleep ratio, then if the result is more
                               2479                 :                :          * than a preset 'minimum sleep time' (say 100ms), call the 'select'
                               2480                 :                :          * function to sleep for a subsecond period ie.
                               2481                 :                :          *
                               2482                 :                :          * select(0, NULL, NULL, NULL, &tvi);
                               2483                 :                :          *
                               2484                 :                :          * This will return after the interval specified in the structure tvi.
                               2485                 :                :          * Finally, call gettimeofday again to save the 'last sleep time'.
                               2486                 :                :          * ----------
                               2487                 :                :          */
                               2488                 :                :     }
 8471 peter_e@gmx.net          2489                 :           4062 :     archprintf(fout, "\\.\n\n\n");
                               2490                 :                : 
 7178 tgl@sss.pgh.pa.us        2491         [ -  + ]:           4062 :     if (ret == -2)
                               2492                 :                :     {
                               2493                 :                :         /* copy data transfer failed */
 2401 peter@eisentraut.org     2494                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
 1298 tgl@sss.pgh.pa.us        2495                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2496                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 5002 rhaas@postgresql.org     2497                 :              0 :         exit_nicely(1);
                               2498                 :                :     }
                               2499                 :                : 
                               2500                 :                :     /* Check command status and return to normal libpq state */
 5002 rhaas@postgresql.org     2501                 :CBC        4062 :     res = PQgetResult(conn);
 5011                          2502         [ -  + ]:           4062 :     if (PQresultStatus(res) != PGRES_COMMAND_OK)
                               2503                 :                :     {
 2401 peter@eisentraut.org     2504                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
 1298 tgl@sss.pgh.pa.us        2505                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2506                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 5002 rhaas@postgresql.org     2507                 :              0 :         exit_nicely(1);
                               2508                 :                :     }
 8518 bruce@momjian.us         2509                 :CBC        4062 :     PQclear(res);
                               2510                 :                : 
                               2511                 :                :     /* Do this to ensure we've pumped libpq back to idle state */
 3434 tgl@sss.pgh.pa.us        2512         [ -  + ]:           4062 :     if (PQgetResult(conn) != NULL)
 2401 peter@eisentraut.org     2513                 :UBC           0 :         pg_log_warning("unexpected extra results during COPY of table \"%s\"",
                               2514                 :                :                        classname);
                               2515                 :                : 
 8571 tgl@sss.pgh.pa.us        2516                 :CBC        4062 :     destroyPQExpBuffer(q);
                               2517                 :                : 
                               2518                 :                :     /* Revert back the setting */
  448 msawada@postgresql.o     2519         [ -  + ]:           4062 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  448 msawada@postgresql.o     2520                 :UBC           0 :         set_restrict_relation_kind(fout, "view, foreign-table");
                               2521                 :                : 
 8571 tgl@sss.pgh.pa.us        2522                 :CBC        4062 :     return 1;
                               2523                 :                : }
                               2524                 :                : 
                               2525                 :                : /*
                               2526                 :                :  * Dump table data using INSERT commands.
                               2527                 :                :  *
                               2528                 :                :  * Caution: when we restore from an archive file direct to database, the
                               2529                 :                :  * INSERT commands emitted by this function have to be parsed by
                               2530                 :                :  * pg_backup_db.c's ExecuteSimpleCommands(), which will not handle comments,
                               2531                 :                :  * E'' strings, or dollar-quoted strings.  So don't emit anything like that.
                               2532                 :                :  */
                               2533                 :                : static int
 1720 peter@eisentraut.org     2534                 :             81 : dumpTableData_insert(Archive *fout, const void *dcontext)
                               2535                 :                : {
 7996 tgl@sss.pgh.pa.us        2536                 :             81 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2537                 :             81 :     TableInfo  *tbinfo = tdinfo->tdtable;
 3575                          2538                 :             81 :     DumpOptions *dopt = fout->dopt;
 8571                          2539                 :             81 :     PQExpBuffer q = createPQExpBuffer();
 4364                          2540                 :             81 :     PQExpBuffer insertStmt = NULL;
                               2541                 :                :     char       *attgenerated;
                               2542                 :                :     PGresult   *res;
                               2543                 :                :     int         nfields,
                               2544                 :                :                 i;
 2426 alvherre@alvh.no-ip.     2545                 :             81 :     int         rows_per_statement = dopt->dump_inserts;
                               2546                 :             81 :     int         rows_this_statement = 0;
                               2547                 :                : 
                               2548                 :                :     /* Temporary allows to access to foreign tables to dump data */
  448 msawada@postgresql.o     2549         [ -  + ]:             81 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  448 msawada@postgresql.o     2550                 :UBC           0 :         set_restrict_relation_kind(fout, "view");
                               2551                 :                : 
                               2552                 :                :     /*
                               2553                 :                :      * If we're going to emit INSERTs with column names, the most efficient
                               2554                 :                :      * way to deal with generated columns is to exclude them entirely.  For
                               2555                 :                :      * INSERTs without column names, we have to emit DEFAULT rather than the
                               2556                 :                :      * actual column value --- but we can save a few cycles by fetching nulls
                               2557                 :                :      * rather than the uninteresting-to-us value.
                               2558                 :                :      */
 1435 tgl@sss.pgh.pa.us        2559                 :CBC          81 :     attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
                               2560                 :             81 :     appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
                               2561                 :             81 :     nfields = 0;
                               2562         [ +  + ]:            251 :     for (i = 0; i < tbinfo->numatts; i++)
                               2563                 :                :     {
                               2564         [ +  + ]:            170 :         if (tbinfo->attisdropped[i])
                               2565                 :              2 :             continue;
                               2566   [ +  +  +  + ]:            168 :         if (tbinfo->attgenerated[i] && dopt->column_inserts)
                               2567                 :              8 :             continue;
                               2568         [ +  + ]:            160 :         if (nfields > 0)
                               2569                 :             86 :             appendPQExpBufferStr(q, ", ");
                               2570         [ +  + ]:            160 :         if (tbinfo->attgenerated[i])
                               2571                 :              8 :             appendPQExpBufferStr(q, "NULL");
                               2572                 :                :         else
                               2573                 :            152 :             appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
                               2574                 :            160 :         attgenerated[nfields] = tbinfo->attgenerated[i];
                               2575                 :            160 :         nfields++;
                               2576                 :                :     }
                               2577                 :                :     /* Servers before 9.4 will complain about zero-column SELECT */
                               2578         [ +  + ]:             81 :     if (nfields == 0)
                               2579                 :              7 :         appendPQExpBufferStr(q, "NULL");
                               2580                 :             81 :     appendPQExpBuffer(q, " FROM ONLY %s",
 2800                          2581                 :             81 :                       fmtQualifiedDumpable(tbinfo));
 5375                          2582         [ -  + ]:             81 :     if (tdinfo->filtercond)
 5375 tgl@sss.pgh.pa.us        2583                 :UBC           0 :         appendPQExpBuffer(q, " %s", tdinfo->filtercond);
                               2584                 :                : 
 5011 rhaas@postgresql.org     2585                 :CBC          81 :     ExecuteSqlStatement(fout, q->data);
                               2586                 :                : 
                               2587                 :                :     while (1)
                               2588                 :                :     {
                               2589                 :            131 :         res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
                               2590                 :                :                               PGRES_TUPLES_OK);
                               2591                 :                : 
                               2592                 :                :         /* cross-check field count, allowing for dummy NULL if any */
 1435 tgl@sss.pgh.pa.us        2593   [ +  +  +  - ]:            131 :         if (nfields != PQnfields(res) &&
                               2594         [ -  + ]:             10 :             !(nfields == 0 && PQnfields(res) == 1))
 1298 tgl@sss.pgh.pa.us        2595                 :UBC           0 :             pg_fatal("wrong number of fields retrieved from table \"%s\"",
                               2596                 :                :                      tbinfo->dobj.name);
                               2597                 :                : 
                               2598                 :                :         /*
                               2599                 :                :          * First time through, we build as much of the INSERT statement as
                               2600                 :                :          * possible in "insertStmt", which we can then just print for each
                               2601                 :                :          * statement. If the table happens to have zero dumpable columns then
                               2602                 :                :          * this will be a complete statement, otherwise it will end in
                               2603                 :                :          * "VALUES" and be ready to have the row's column values printed.
                               2604                 :                :          */
 2426 alvherre@alvh.no-ip.     2605         [ +  + ]:CBC         131 :         if (insertStmt == NULL)
                               2606                 :                :         {
                               2607                 :                :             TableInfo  *targettab;
                               2608                 :                : 
                               2609                 :             81 :             insertStmt = createPQExpBuffer();
                               2610                 :                : 
                               2611                 :                :             /*
                               2612                 :                :              * When load-via-partition-root is set or forced, get the root
                               2613                 :                :              * table name for the partition table, so that we can reload data
                               2614                 :                :              * through the root table.
                               2615                 :                :              */
  955 tgl@sss.pgh.pa.us        2616         [ +  + ]:             81 :             if (tbinfo->ispartition &&
                               2617   [ +  -  +  + ]:             48 :                 (dopt->load_via_partition_root ||
                               2618                 :             24 :                  forcePartitionRootLoad(tbinfo)))
 2426 alvherre@alvh.no-ip.     2619                 :              7 :                 targettab = getRootTableInfo(tbinfo);
                               2620                 :                :             else
                               2621                 :             74 :                 targettab = tbinfo;
                               2622                 :                : 
                               2623                 :             81 :             appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
                               2624                 :             81 :                               fmtQualifiedDumpable(targettab));
                               2625                 :                : 
                               2626                 :                :             /* corner case for zero-column table */
                               2627         [ +  + ]:             81 :             if (nfields == 0)
                               2628                 :                :             {
                               2629                 :              7 :                 appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
                               2630                 :                :             }
                               2631                 :                :             else
                               2632                 :                :             {
                               2633                 :                :                 /* append the list of column names if required */
                               2634         [ +  + ]:             74 :                 if (dopt->column_inserts)
                               2635                 :                :                 {
                               2636                 :             33 :                     appendPQExpBufferChar(insertStmt, '(');
                               2637         [ +  + ]:            100 :                     for (int field = 0; field < nfields; field++)
                               2638                 :                :                     {
                               2639         [ +  + ]:             67 :                         if (field > 0)
                               2640                 :             34 :                             appendPQExpBufferStr(insertStmt, ", ");
                               2641                 :             67 :                         appendPQExpBufferStr(insertStmt,
                               2642                 :             67 :                                              fmtId(PQfname(res, field)));
                               2643                 :                :                     }
                               2644                 :             33 :                     appendPQExpBufferStr(insertStmt, ") ");
                               2645                 :                :                 }
                               2646                 :                : 
                               2647         [ +  + ]:             74 :                 if (tbinfo->needs_override)
                               2648                 :              2 :                     appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
                               2649                 :                : 
                               2650                 :             74 :                 appendPQExpBufferStr(insertStmt, "VALUES");
                               2651                 :                :             }
                               2652                 :                :         }
                               2653                 :                : 
                               2654         [ +  + ]:           3400 :         for (int tuple = 0; tuple < PQntuples(res); tuple++)
                               2655                 :                :         {
                               2656                 :                :             /* Write the INSERT if not in the middle of a multi-row INSERT. */
                               2657         [ +  + ]:           3269 :             if (rows_this_statement == 0)
                               2658                 :           3263 :                 archputs(insertStmt->data, fout);
                               2659                 :                : 
                               2660                 :                :             /*
                               2661                 :                :              * If it is zero-column table then we've already written the
                               2662                 :                :              * complete statement, which will mean we've disobeyed
                               2663                 :                :              * --rows-per-insert when it's set greater than 1.  We do support
                               2664                 :                :              * a way to make this multi-row with: SELECT UNION ALL SELECT
                               2665                 :                :              * UNION ALL ... but that's non-standard so we should avoid it
                               2666                 :                :              * given that using INSERTs is mostly only ever needed for
                               2667                 :                :              * cross-database exports.
                               2668                 :                :              */
 4364 tgl@sss.pgh.pa.us        2669         [ +  + ]:           3269 :             if (nfields == 0)
                               2670                 :              6 :                 continue;
                               2671                 :                : 
                               2672                 :                :             /* Emit a row heading */
 2426 alvherre@alvh.no-ip.     2673         [ +  + ]:           3263 :             if (rows_per_statement == 1)
                               2674                 :           3254 :                 archputs(" (", fout);
                               2675         [ +  + ]:              9 :             else if (rows_this_statement > 0)
                               2676                 :              6 :                 archputs(",\n\t(", fout);
                               2677                 :                :             else
                               2678                 :              3 :                 archputs("\n\t(", fout);
                               2679                 :                : 
                               2680         [ +  + ]:           9845 :             for (int field = 0; field < nfields; field++)
                               2681                 :                :             {
 8571 tgl@sss.pgh.pa.us        2682         [ +  + ]:           6582 :                 if (field > 0)
 4364                          2683                 :           3319 :                     archputs(", ", fout);
 1435                          2684         [ +  + ]:           6582 :                 if (attgenerated[field])
                               2685                 :                :                 {
 2403 peter@eisentraut.org     2686                 :              2 :                     archputs("DEFAULT", fout);
                               2687                 :              2 :                     continue;
                               2688                 :                :                 }
 8571 tgl@sss.pgh.pa.us        2689         [ +  + ]:           6580 :                 if (PQgetisnull(res, tuple, field))
                               2690                 :                :                 {
 4364                          2691                 :             83 :                     archputs("NULL", fout);
 8571                          2692                 :             83 :                     continue;
                               2693                 :                :                 }
                               2694                 :                : 
                               2695                 :                :                 /* XXX This code is partially duplicated in ruleutils.c */
                               2696   [ +  +  +  + ]:           6497 :                 switch (PQftype(res, field))
                               2697                 :                :                 {
                               2698                 :           4469 :                     case INT2OID:
                               2699                 :                :                     case INT4OID:
                               2700                 :                :                     case INT8OID:
                               2701                 :                :                     case OIDOID:
                               2702                 :                :                     case FLOAT4OID:
                               2703                 :                :                     case FLOAT8OID:
                               2704                 :                :                     case NUMERICOID:
                               2705                 :                :                         {
                               2706                 :                :                             /*
                               2707                 :                :                              * These types are printed without quotes unless
                               2708                 :                :                              * they contain values that aren't accepted by the
                               2709                 :                :                              * scanner unquoted (e.g., 'NaN').  Note that
                               2710                 :                :                              * strtod() and friends might accept NaN, so we
                               2711                 :                :                              * can't use that to test.
                               2712                 :                :                              *
                               2713                 :                :                              * In reality we only need to defend against
                               2714                 :                :                              * infinity and NaN, so we need not get too crazy
                               2715                 :                :                              * about pattern matching here.
                               2716                 :                :                              */
 8454 bruce@momjian.us         2717                 :           4469 :                             const char *s = PQgetvalue(res, tuple, field);
                               2718                 :                : 
                               2719         [ +  + ]:           4469 :                             if (strspn(s, "0123456789 +-eE.") == strlen(s))
 4364 tgl@sss.pgh.pa.us        2720                 :           4467 :                                 archputs(s, fout);
                               2721                 :                :                             else
 8454 bruce@momjian.us         2722                 :              2 :                                 archprintf(fout, "'%s'", s);
                               2723                 :                :                         }
                               2724                 :           4469 :                         break;
                               2725                 :                : 
 8571 tgl@sss.pgh.pa.us        2726                 :              2 :                     case BITOID:
                               2727                 :                :                     case VARBITOID:
                               2728                 :              2 :                         archprintf(fout, "B'%s'",
                               2729                 :                :                                    PQgetvalue(res, tuple, field));
                               2730                 :              2 :                         break;
                               2731                 :                : 
 8471 peter_e@gmx.net          2732                 :              4 :                     case BOOLOID:
 8454 bruce@momjian.us         2733         [ +  + ]:              4 :                         if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
 4364 tgl@sss.pgh.pa.us        2734                 :              2 :                             archputs("true", fout);
                               2735                 :                :                         else
                               2736                 :              2 :                             archputs("false", fout);
 8471 peter_e@gmx.net          2737                 :              4 :                         break;
                               2738                 :                : 
                               2739                 :           2022 :                     default:
                               2740                 :                :                         /* All other types are printed as string literals. */
 8571 tgl@sss.pgh.pa.us        2741                 :           2022 :                         resetPQExpBuffer(q);
 7092                          2742                 :           2022 :                         appendStringLiteralAH(q,
                               2743                 :                :                                               PQgetvalue(res, tuple, field),
                               2744                 :                :                                               fout);
 7579                          2745                 :           2022 :                         archputs(q->data, fout);
 8571                          2746                 :           2022 :                         break;
                               2747                 :                :                 }
                               2748                 :                :             }
                               2749                 :                : 
                               2750                 :                :             /* Terminate the row ... */
 2426 alvherre@alvh.no-ip.     2751                 :           3263 :             archputs(")", fout);
                               2752                 :                : 
                               2753                 :                :             /* ... and the statement, if the target no. of rows is reached */
                               2754         [ +  + ]:           3263 :             if (++rows_this_statement >= rows_per_statement)
                               2755                 :                :             {
                               2756         [ -  + ]:           3256 :                 if (dopt->do_nothing)
 2426 alvherre@alvh.no-ip.     2757                 :UBC           0 :                     archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2758                 :                :                 else
 2426 alvherre@alvh.no-ip.     2759                 :CBC        3256 :                     archputs(";\n", fout);
                               2760                 :                :                 /* Reset the row counter */
                               2761                 :           3256 :                 rows_this_statement = 0;
                               2762                 :                :             }
                               2763                 :                :         }
                               2764                 :                : 
 5011 rhaas@postgresql.org     2765         [ +  + ]:            131 :         if (PQntuples(res) <= 0)
                               2766                 :                :         {
                               2767                 :             81 :             PQclear(res);
                               2768                 :             81 :             break;
                               2769                 :                :         }
                               2770                 :             50 :         PQclear(res);
                               2771                 :                :     }
                               2772                 :                : 
                               2773                 :                :     /* Terminate any statements that didn't make the row count. */
 2426 alvherre@alvh.no-ip.     2774         [ +  + ]:             81 :     if (rows_this_statement > 0)
                               2775                 :                :     {
                               2776         [ -  + ]:              1 :         if (dopt->do_nothing)
 2426 alvherre@alvh.no-ip.     2777                 :UBC           0 :             archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2778                 :                :         else
 2426 alvherre@alvh.no-ip.     2779                 :CBC           1 :             archputs(";\n", fout);
                               2780                 :                :     }
                               2781                 :                : 
 4364 tgl@sss.pgh.pa.us        2782                 :             81 :     archputs("\n\n", fout);
                               2783                 :                : 
 5011 rhaas@postgresql.org     2784                 :             81 :     ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
                               2785                 :                : 
 8571 tgl@sss.pgh.pa.us        2786                 :             81 :     destroyPQExpBuffer(q);
 4364                          2787         [ +  - ]:             81 :     if (insertStmt != NULL)
                               2788                 :             81 :         destroyPQExpBuffer(insertStmt);
 1435                          2789                 :             81 :     free(attgenerated);
                               2790                 :                : 
                               2791                 :                :     /* Revert back the setting */
  448 msawada@postgresql.o     2792         [ -  + ]:             81 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  448 msawada@postgresql.o     2793                 :UBC           0 :         set_restrict_relation_kind(fout, "view, foreign-table");
                               2794                 :                : 
 8571 tgl@sss.pgh.pa.us        2795                 :CBC          81 :     return 1;
                               2796                 :                : }
                               2797                 :                : 
                               2798                 :                : /*
                               2799                 :                :  * getRootTableInfo:
                               2800                 :                :  *     get the root TableInfo for the given partition table.
                               2801                 :                :  */
                               2802                 :                : static TableInfo *
 1720 peter@eisentraut.org     2803                 :             79 : getRootTableInfo(const TableInfo *tbinfo)
                               2804                 :                : {
                               2805                 :                :     TableInfo  *parentTbinfo;
                               2806                 :                : 
 2996 rhaas@postgresql.org     2807         [ -  + ]:             79 :     Assert(tbinfo->ispartition);
                               2808         [ -  + ]:             79 :     Assert(tbinfo->numParents == 1);
                               2809                 :                : 
                               2810                 :             79 :     parentTbinfo = tbinfo->parents[0];
                               2811         [ -  + ]:             79 :     while (parentTbinfo->ispartition)
                               2812                 :                :     {
 2996 rhaas@postgresql.org     2813         [ #  # ]:UBC           0 :         Assert(parentTbinfo->numParents == 1);
                               2814                 :              0 :         parentTbinfo = parentTbinfo->parents[0];
                               2815                 :                :     }
                               2816                 :                : 
 2996 rhaas@postgresql.org     2817                 :CBC          79 :     return parentTbinfo;
                               2818                 :                : }
                               2819                 :                : 
                               2820                 :                : /*
                               2821                 :                :  * forcePartitionRootLoad
                               2822                 :                :  *     Check if we must force load_via_partition_root for this partition.
                               2823                 :                :  *
                               2824                 :                :  * This is required if any level of ancestral partitioned table has an
                               2825                 :                :  * unsafe partitioning scheme.
                               2826                 :                :  */
                               2827                 :                : static bool
  955 tgl@sss.pgh.pa.us        2828                 :           1048 : forcePartitionRootLoad(const TableInfo *tbinfo)
                               2829                 :                : {
                               2830                 :                :     TableInfo  *parentTbinfo;
                               2831                 :                : 
                               2832         [ -  + ]:           1048 :     Assert(tbinfo->ispartition);
                               2833         [ -  + ]:           1048 :     Assert(tbinfo->numParents == 1);
                               2834                 :                : 
                               2835                 :           1048 :     parentTbinfo = tbinfo->parents[0];
                               2836         [ +  + ]:           1048 :     if (parentTbinfo->unsafe_partitions)
                               2837                 :             79 :         return true;
                               2838         [ +  + ]:           1185 :     while (parentTbinfo->ispartition)
                               2839                 :                :     {
                               2840         [ -  + ]:            216 :         Assert(parentTbinfo->numParents == 1);
                               2841                 :            216 :         parentTbinfo = parentTbinfo->parents[0];
                               2842         [ -  + ]:            216 :         if (parentTbinfo->unsafe_partitions)
  955 tgl@sss.pgh.pa.us        2843                 :UBC           0 :             return true;
                               2844                 :                :     }
                               2845                 :                : 
  955 tgl@sss.pgh.pa.us        2846                 :CBC         969 :     return false;
                               2847                 :                : }
                               2848                 :                : 
                               2849                 :                : /*
                               2850                 :                :  * dumpTableData -
                               2851                 :                :  *    dump the contents of a single table
                               2852                 :                :  *
                               2853                 :                :  * Actually, this just makes an ArchiveEntry for the table contents.
                               2854                 :                :  */
                               2855                 :                : static void
 1720 peter@eisentraut.org     2856                 :           4224 : dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
                               2857                 :                : {
 3575 tgl@sss.pgh.pa.us        2858                 :           4224 :     DumpOptions *dopt = fout->dopt;
 7996                          2859                 :           4224 :     TableInfo  *tbinfo = tdinfo->tdtable;
 5374                          2860                 :           4224 :     PQExpBuffer copyBuf = createPQExpBuffer();
 4600 andrew@dunslane.net      2861                 :           4224 :     PQExpBuffer clistBuf = createPQExpBuffer();
                               2862                 :                :     DataDumperPtr dumpFn;
  955 tgl@sss.pgh.pa.us        2863                 :           4224 :     char       *tdDefn = NULL;
                               2864                 :                :     char       *copyStmt;
                               2865                 :                :     const char *copyFrom;
                               2866                 :                : 
                               2867                 :                :     /* We had better have loaded per-column details about this table */
 1846                          2868         [ -  + ]:           4224 :     Assert(tbinfo->interesting);
                               2869                 :                : 
                               2870                 :                :     /*
                               2871                 :                :      * When load-via-partition-root is set or forced, get the root table name
                               2872                 :                :      * for the partition table, so that we can reload data through the root
                               2873                 :                :      * table.  Then construct a comment to be inserted into the TOC entry's
                               2874                 :                :      * defn field, so that such cases can be identified reliably.
                               2875                 :                :      */
  955                          2876         [ +  + ]:           4224 :     if (tbinfo->ispartition &&
                               2877   [ +  -  +  + ]:           2048 :         (dopt->load_via_partition_root ||
                               2878                 :           1024 :          forcePartitionRootLoad(tbinfo)))
                               2879                 :             72 :     {
                               2880                 :                :         TableInfo  *parentTbinfo;
                               2881                 :                :         char       *sanitized;
                               2882                 :                : 
                               2883                 :             72 :         parentTbinfo = getRootTableInfo(tbinfo);
                               2884                 :             72 :         copyFrom = fmtQualifiedDumpable(parentTbinfo);
   77 noah@leadboat.com        2885                 :             72 :         sanitized = sanitize_line(copyFrom, true);
  955 tgl@sss.pgh.pa.us        2886                 :             72 :         printfPQExpBuffer(copyBuf, "-- load via partition root %s",
                               2887                 :                :                           sanitized);
   77 noah@leadboat.com        2888                 :             72 :         free(sanitized);
  955 tgl@sss.pgh.pa.us        2889                 :             72 :         tdDefn = pg_strdup(copyBuf->data);
                               2890                 :                :     }
                               2891                 :                :     else
                               2892                 :           4152 :         copyFrom = fmtQualifiedDumpable(tbinfo);
                               2893                 :                : 
 1937 alvherre@alvh.no-ip.     2894         [ +  + ]:           4224 :     if (dopt->dump_inserts == 0)
                               2895                 :                :     {
                               2896                 :                :         /* Dump/restore using COPY */
 7996 tgl@sss.pgh.pa.us        2897                 :           4143 :         dumpFn = dumpTableData_copy;
                               2898                 :                :         /* must use 2 steps here 'cause fmtId is nonreentrant */
  955                          2899                 :           4143 :         printfPQExpBuffer(copyBuf, "COPY %s ",
                               2900                 :                :                           copyFrom);
 2533 andres@anarazel.de       2901                 :           4143 :         appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
                               2902                 :                :                           fmtCopyColumnList(tbinfo, clistBuf));
 7996 tgl@sss.pgh.pa.us        2903                 :           4143 :         copyStmt = copyBuf->data;
                               2904                 :                :     }
                               2905                 :                :     else
                               2906                 :                :     {
                               2907                 :                :         /* Restore using INSERT */
                               2908                 :             81 :         dumpFn = dumpTableData_insert;
                               2909                 :             81 :         copyStmt = NULL;
                               2910                 :                :     }
                               2911                 :                : 
                               2912                 :                :     /*
                               2913                 :                :      * Note: although the TableDataInfo is a full DumpableObject, we treat its
                               2914                 :                :      * dependency on its table as "special" and pass it to ArchiveEntry now.
                               2915                 :                :      * See comments for BuildArchiveDependencies.
                               2916                 :                :      */
 3491 sfrost@snowman.net       2917         [ +  - ]:           4224 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2918                 :                :     {
                               2919                 :                :         TocEntry   *te;
                               2920                 :                : 
 2600 tgl@sss.pgh.pa.us        2921                 :           4224 :         te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.     2922                 :           4224 :                           ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2923                 :                :                                        .namespace = tbinfo->dobj.namespace->dobj.name,
                               2924                 :                :                                        .owner = tbinfo->rolname,
                               2925                 :                :                                        .description = "TABLE DATA",
                               2926                 :                :                                        .section = SECTION_DATA,
                               2927                 :                :                                        .createStmt = tdDefn,
                               2928                 :                :                                        .copyStmt = copyStmt,
                               2929                 :                :                                        .deps = &(tbinfo->dobj.dumpId),
                               2930                 :                :                                        .nDeps = 1,
                               2931                 :                :                                        .dumpFn = dumpFn,
                               2932                 :                :                                        .dumpArg = tdinfo));
                               2933                 :                : 
                               2934                 :                :         /*
                               2935                 :                :          * Set the TocEntry's dataLength in case we are doing a parallel dump
                               2936                 :                :          * and want to order dump jobs by table size.  We choose to measure
                               2937                 :                :          * dataLength in table pages (including TOAST pages) during dump, so
                               2938                 :                :          * no scaling is needed.
                               2939                 :                :          *
                               2940                 :                :          * However, relpages is declared as "integer" in pg_class, and hence
                               2941                 :                :          * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
                               2942                 :                :          * Cast so that we get the right interpretation of table sizes
                               2943                 :                :          * exceeding INT_MAX pages.
                               2944                 :                :          */
 2600 tgl@sss.pgh.pa.us        2945                 :           4224 :         te->dataLength = (BlockNumber) tbinfo->relpages;
 1421                          2946                 :           4224 :         te->dataLength += (BlockNumber) tbinfo->toastpages;
                               2947                 :                : 
                               2948                 :                :         /*
                               2949                 :                :          * If pgoff_t is only 32 bits wide, the above refinement is useless,
                               2950                 :                :          * and instead we'd better worry about integer overflow.  Clamp to
                               2951                 :                :          * INT_MAX if the correct result exceeds that.
                               2952                 :                :          */
                               2953                 :                :         if (sizeof(te->dataLength) == 4 &&
                               2954                 :                :             (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
                               2955                 :                :              te->dataLength < 0))
                               2956                 :                :             te->dataLength = INT_MAX;
                               2957                 :                :     }
                               2958                 :                : 
 7996                          2959                 :           4224 :     destroyPQExpBuffer(copyBuf);
 4600 andrew@dunslane.net      2960                 :           4224 :     destroyPQExpBuffer(clistBuf);
 7996 tgl@sss.pgh.pa.us        2961                 :           4224 : }
                               2962                 :                : 
                               2963                 :                : /*
                               2964                 :                :  * refreshMatViewData -
                               2965                 :                :  *    load or refresh the contents of a single materialized view
                               2966                 :                :  *
                               2967                 :                :  * Actually, this just makes an ArchiveEntry for the REFRESH MATERIALIZED VIEW
                               2968                 :                :  * statement.
                               2969                 :                :  */
                               2970                 :                : static void
 1720 peter@eisentraut.org     2971                 :            348 : refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
                               2972                 :                : {
 4621 kgrittn@postgresql.o     2973                 :            348 :     TableInfo  *tbinfo = tdinfo->tdtable;
                               2974                 :                :     PQExpBuffer q;
                               2975                 :                : 
                               2976                 :                :     /* If the materialized view is not flagged as populated, skip this. */
 4557 tgl@sss.pgh.pa.us        2977         [ +  + ]:            348 :     if (!tbinfo->relispopulated)
 4621 kgrittn@postgresql.o     2978                 :             68 :         return;
                               2979                 :                : 
                               2980                 :            280 :     q = createPQExpBuffer();
                               2981                 :                : 
                               2982                 :            280 :     appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
 2800 tgl@sss.pgh.pa.us        2983                 :            280 :                       fmtQualifiedDumpable(tbinfo));
                               2984                 :                : 
 3491 sfrost@snowman.net       2985         [ +  - ]:            280 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2986                 :            280 :         ArchiveEntry(fout,
                               2987                 :                :                      tdinfo->dobj.catId, /* catalog ID */
 3050 tgl@sss.pgh.pa.us        2988                 :            280 :                      tdinfo->dobj.dumpId,    /* dump ID */
 2460 alvherre@alvh.no-ip.     2989                 :            280 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2990                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               2991                 :                :                                   .owner = tbinfo->rolname,
                               2992                 :                :                                   .description = "MATERIALIZED VIEW DATA",
                               2993                 :                :                                   .section = SECTION_POST_DATA,
                               2994                 :                :                                   .createStmt = q->data,
                               2995                 :                :                                   .deps = tdinfo->dobj.dependencies,
                               2996                 :                :                                   .nDeps = tdinfo->dobj.nDeps));
                               2997                 :                : 
 4621 kgrittn@postgresql.o     2998                 :            280 :     destroyPQExpBuffer(q);
                               2999                 :                : }
                               3000                 :                : 
                               3001                 :                : /*
                               3002                 :                :  * getTableData -
                               3003                 :                :  *    set up dumpable objects representing the contents of tables
                               3004                 :                :  */
                               3005                 :                : static void
 2533 andres@anarazel.de       3006                 :            181 : getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
                               3007                 :                : {
                               3008                 :                :     int         i;
                               3009                 :                : 
 8571 tgl@sss.pgh.pa.us        3010         [ +  + ]:          47921 :     for (i = 0; i < numTables; i++)
                               3011                 :                :     {
 3352 peter_e@gmx.net          3012   [ +  +  +  + ]:          47740 :         if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
                               3013         [ +  + ]:            927 :             (!relkind || tblinfo[i].relkind == relkind))
 2533 andres@anarazel.de       3014                 :           5889 :             makeTableDataInfo(dopt, &(tblinfo[i]));
                               3015                 :                :     }
 5375 tgl@sss.pgh.pa.us        3016                 :            181 : }
                               3017                 :                : 
                               3018                 :                : /*
                               3019                 :                :  * Make a dumpable object for the data of this specific table
                               3020                 :                :  *
                               3021                 :                :  * Note: we make a TableDataInfo if and only if we are going to dump the
                               3022                 :                :  * table data; the "dump" field in such objects isn't very interesting.
                               3023                 :                :  */
                               3024                 :                : static void
 2533 andres@anarazel.de       3025                 :           6000 : makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
                               3026                 :                : {
                               3027                 :                :     TableDataInfo *tdinfo;
                               3028                 :                : 
                               3029                 :                :     /*
                               3030                 :                :      * Nothing to do if we already decided to dump the table.  This will
                               3031                 :                :      * happen for "config" tables.
                               3032                 :                :      */
 5010 tgl@sss.pgh.pa.us        3033         [ +  + ]:           6000 :     if (tbinfo->dataObj != NULL)
                               3034                 :              1 :         return;
                               3035                 :                : 
                               3036                 :                :     /* Skip VIEWs (no data to dump) */
                               3037         [ +  + ]:           5999 :     if (tbinfo->relkind == RELKIND_VIEW)
                               3038                 :            484 :         return;
                               3039                 :                :     /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
 2042 alvherre@alvh.no-ip.     3040         [ +  + ]:           5515 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                               3041         [ +  + ]:             38 :         (foreign_servers_include_oids.head == NULL ||
 1992 tgl@sss.pgh.pa.us        3042         [ +  + ]:              4 :          !simple_oid_list_member(&foreign_servers_include_oids,
                               3043                 :                :                                  tbinfo->foreign_server)))
 5010                          3044                 :             37 :         return;
                               3045                 :                :     /* Skip partitioned tables (data in partitions) */
 3246 rhaas@postgresql.org     3046         [ +  + ]:           5478 :     if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
                               3047                 :            487 :         return;
                               3048                 :                : 
                               3049                 :                :     /* Don't dump data in unlogged tables, if so requested */
 5010 tgl@sss.pgh.pa.us        3050         [ +  + ]:           4991 :     if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
 4031 alvherre@alvh.no-ip.     3051         [ +  + ]:             41 :         dopt->no_unlogged_table_data)
 5010 tgl@sss.pgh.pa.us        3052                 :             18 :         return;
                               3053                 :                : 
                               3054                 :                :     /* Check that the data is not explicitly excluded */
                               3055         [ +  + ]:           4973 :     if (simple_oid_list_member(&tabledata_exclude_oids,
                               3056                 :                :                                tbinfo->dobj.catId.oid))
                               3057                 :              8 :         return;
                               3058                 :                : 
                               3059                 :                :     /* OK, let's dump it */
 5085 bruce@momjian.us         3060                 :           4965 :     tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
                               3061                 :                : 
 4621 kgrittn@postgresql.o     3062         [ +  + ]:           4965 :     if (tbinfo->relkind == RELKIND_MATVIEW)
                               3063                 :            348 :         tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
 3352 peter_e@gmx.net          3064         [ +  + ]:           4617 :     else if (tbinfo->relkind == RELKIND_SEQUENCE)
                               3065                 :            393 :         tdinfo->dobj.objType = DO_SEQUENCE_SET;
                               3066                 :                :     else
 4621 kgrittn@postgresql.o     3067                 :           4224 :         tdinfo->dobj.objType = DO_TABLE_DATA;
                               3068                 :                : 
                               3069                 :                :     /*
                               3070                 :                :      * Note: use tableoid 0 so that this object won't be mistaken for
                               3071                 :                :      * something that pg_depend entries apply to.
                               3072                 :                :      */
 5375 tgl@sss.pgh.pa.us        3073                 :           4965 :     tdinfo->dobj.catId.tableoid = 0;
                               3074                 :           4965 :     tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               3075                 :           4965 :     AssignDumpId(&tdinfo->dobj);
                               3076                 :           4965 :     tdinfo->dobj.name = tbinfo->dobj.name;
                               3077                 :           4965 :     tdinfo->dobj.namespace = tbinfo->dobj.namespace;
                               3078                 :           4965 :     tdinfo->tdtable = tbinfo;
 5314 bruce@momjian.us         3079                 :           4965 :     tdinfo->filtercond = NULL;   /* might get set later */
 5375 tgl@sss.pgh.pa.us        3080                 :           4965 :     addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
                               3081                 :                : 
                               3082                 :                :     /* A TableDataInfo contains data, of course */
 1421                          3083                 :           4965 :     tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               3084                 :                : 
 5375                          3085                 :           4965 :     tbinfo->dataObj = tdinfo;
                               3086                 :                : 
                               3087                 :                :     /*
                               3088                 :                :      * Materialized view statistics must be restored after the data, because
                               3089                 :                :      * REFRESH MATERIALIZED VIEW replaces the storage and resets the stats.
                               3090                 :                :      *
                               3091                 :                :      * The dependency is added here because the statistics objects are created
                               3092                 :                :      * first.
                               3093                 :                :      */
  213 jdavis@postgresql.or     3094   [ +  +  +  + ]:           4965 :     if (tbinfo->relkind == RELKIND_MATVIEW && tbinfo->stats != NULL)
                               3095                 :                :     {
                               3096                 :            271 :         tbinfo->stats->section = SECTION_POST_DATA;
                               3097                 :            271 :         addObjectDependency(&tbinfo->stats->dobj, tdinfo->dobj.dumpId);
                               3098                 :                :     }
                               3099                 :                : 
                               3100                 :                :     /* Make sure that we'll collect per-column info for this table. */
 1846 tgl@sss.pgh.pa.us        3101                 :           4965 :     tbinfo->interesting = true;
                               3102                 :                : }
                               3103                 :                : 
                               3104                 :                : /*
                               3105                 :                :  * The refresh for a materialized view must be dependent on the refresh for
                               3106                 :                :  * any materialized view that this one is dependent on.
                               3107                 :                :  *
                               3108                 :                :  * This must be called after all the objects are created, but before they are
                               3109                 :                :  * sorted.
                               3110                 :                :  */
                               3111                 :                : static void
 4621 kgrittn@postgresql.o     3112                 :            149 : buildMatViewRefreshDependencies(Archive *fout)
                               3113                 :                : {
                               3114                 :                :     PQExpBuffer query;
                               3115                 :                :     PGresult   *res;
                               3116                 :                :     int         ntups,
                               3117                 :                :                 i;
                               3118                 :                :     int         i_classid,
                               3119                 :                :                 i_objid,
                               3120                 :                :                 i_refobjid;
                               3121                 :                : 
                               3122                 :                :     /* No Mat Views before 9.3. */
 4611                          3123         [ -  + ]:            149 :     if (fout->remoteVersion < 90300)
 4611 kgrittn@postgresql.o     3124                 :UBC           0 :         return;
                               3125                 :                : 
 4611 kgrittn@postgresql.o     3126                 :CBC         149 :     query = createPQExpBuffer();
                               3127                 :                : 
 4361 heikki.linnakangas@i     3128                 :            149 :     appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
                               3129                 :                :                          "( "
                               3130                 :                :                          "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
                               3131                 :                :                          "FROM pg_depend d1 "
                               3132                 :                :                          "JOIN pg_class c1 ON c1.oid = d1.objid "
                               3133                 :                :                          "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
                               3134                 :                :                          " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
                               3135                 :                :                          "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
                               3136                 :                :                          "AND d2.objid = r1.oid "
                               3137                 :                :                          "AND d2.refobjid <> d1.objid "
                               3138                 :                :                          "JOIN pg_class c2 ON c2.oid = d2.refobjid "
                               3139                 :                :                          "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               3140                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               3141                 :                :                          "WHERE d1.classid = 'pg_class'::regclass "
                               3142                 :                :                          "UNION "
                               3143                 :                :                          "SELECT w.objid, d3.refobjid, c3.relkind "
                               3144                 :                :                          "FROM w "
                               3145                 :                :                          "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
                               3146                 :                :                          "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
                               3147                 :                :                          "AND d3.objid = r3.oid "
                               3148                 :                :                          "AND d3.refobjid <> w.refobjid "
                               3149                 :                :                          "JOIN pg_class c3 ON c3.oid = d3.refobjid "
                               3150                 :                :                          "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               3151                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               3152                 :                :                          ") "
                               3153                 :                :                          "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
                               3154                 :                :                          "FROM w "
                               3155                 :                :                          "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
                               3156                 :                : 
 4621 kgrittn@postgresql.o     3157                 :            149 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               3158                 :                : 
                               3159                 :            149 :     ntups = PQntuples(res);
                               3160                 :                : 
                               3161                 :            149 :     i_classid = PQfnumber(res, "classid");
                               3162                 :            149 :     i_objid = PQfnumber(res, "objid");
                               3163                 :            149 :     i_refobjid = PQfnumber(res, "refobjid");
                               3164                 :                : 
                               3165         [ +  + ]:            413 :     for (i = 0; i < ntups; i++)
                               3166                 :                :     {
                               3167                 :                :         CatalogId   objId;
                               3168                 :                :         CatalogId   refobjId;
                               3169                 :                :         DumpableObject *dobj;
                               3170                 :                :         DumpableObject *refdobj;
                               3171                 :                :         TableInfo  *tbinfo;
                               3172                 :                :         TableInfo  *reftbinfo;
                               3173                 :                : 
                               3174                 :            264 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                               3175                 :            264 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                               3176                 :            264 :         refobjId.tableoid = objId.tableoid;
                               3177                 :            264 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                               3178                 :                : 
                               3179                 :            264 :         dobj = findObjectByCatalogId(objId);
                               3180         [ -  + ]:            264 :         if (dobj == NULL)
                               3181                 :             48 :             continue;
                               3182                 :                : 
                               3183         [ -  + ]:            264 :         Assert(dobj->objType == DO_TABLE);
                               3184                 :            264 :         tbinfo = (TableInfo *) dobj;
                               3185         [ -  + ]:            264 :         Assert(tbinfo->relkind == RELKIND_MATVIEW);
                               3186                 :            264 :         dobj = (DumpableObject *) tbinfo->dataObj;
                               3187         [ +  + ]:            264 :         if (dobj == NULL)
                               3188                 :             48 :             continue;
                               3189         [ -  + ]:            216 :         Assert(dobj->objType == DO_REFRESH_MATVIEW);
                               3190                 :                : 
                               3191                 :            216 :         refdobj = findObjectByCatalogId(refobjId);
                               3192         [ -  + ]:            216 :         if (refdobj == NULL)
 4621 kgrittn@postgresql.o     3193                 :UBC           0 :             continue;
                               3194                 :                : 
 4621 kgrittn@postgresql.o     3195         [ -  + ]:CBC         216 :         Assert(refdobj->objType == DO_TABLE);
                               3196                 :            216 :         reftbinfo = (TableInfo *) refdobj;
                               3197         [ -  + ]:            216 :         Assert(reftbinfo->relkind == RELKIND_MATVIEW);
                               3198                 :            216 :         refdobj = (DumpableObject *) reftbinfo->dataObj;
                               3199         [ -  + ]:            216 :         if (refdobj == NULL)
 4621 kgrittn@postgresql.o     3200                 :UBC           0 :             continue;
 4621 kgrittn@postgresql.o     3201         [ -  + ]:CBC         216 :         Assert(refdobj->objType == DO_REFRESH_MATVIEW);
                               3202                 :                : 
                               3203                 :            216 :         addObjectDependency(dobj, refdobj->dumpId);
                               3204                 :                : 
 4557 tgl@sss.pgh.pa.us        3205         [ +  + ]:            216 :         if (!reftbinfo->relispopulated)
                               3206                 :             34 :             tbinfo->relispopulated = false;
                               3207                 :                :     }
                               3208                 :                : 
 4621 kgrittn@postgresql.o     3209                 :            149 :     PQclear(res);
                               3210                 :                : 
                               3211                 :            149 :     destroyPQExpBuffer(query);
                               3212                 :                : }
                               3213                 :                : 
                               3214                 :                : /*
                               3215                 :                :  * getTableDataFKConstraints -
                               3216                 :                :  *    add dump-order dependencies reflecting foreign key constraints
                               3217                 :                :  *
                               3218                 :                :  * This code is executed only in a data-only dump --- in schema+data dumps
                               3219                 :                :  * we handle foreign key issues by not creating the FK constraints until
                               3220                 :                :  * after the data is loaded.  In a data-only dump, however, we want to
                               3221                 :                :  * order the table data objects in such a way that a table's referenced
                               3222                 :                :  * tables are restored first.  (In the presence of circular references or
                               3223                 :                :  * self-references this may be impossible; we'll detect and complain about
                               3224                 :                :  * that during the dependency sorting step.)
                               3225                 :                :  */
                               3226                 :                : static void
 6258 tgl@sss.pgh.pa.us        3227                 :              7 : getTableDataFKConstraints(void)
                               3228                 :                : {
                               3229                 :                :     DumpableObject **dobjs;
                               3230                 :                :     int         numObjs;
                               3231                 :                :     int         i;
                               3232                 :                : 
                               3233                 :                :     /* Search through all the dumpable objects for FK constraints */
                               3234                 :              7 :     getDumpableObjects(&dobjs, &numObjs);
                               3235         [ +  + ]:          30682 :     for (i = 0; i < numObjs; i++)
                               3236                 :                :     {
                               3237         [ +  + ]:          30675 :         if (dobjs[i]->objType == DO_FK_CONSTRAINT)
                               3238                 :                :         {
                               3239                 :              8 :             ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
                               3240                 :                :             TableInfo  *ftable;
                               3241                 :                : 
                               3242                 :                :             /* Not interesting unless both tables are to be dumped */
                               3243         [ +  - ]:              8 :             if (cinfo->contable == NULL ||
                               3244         [ +  + ]:              8 :                 cinfo->contable->dataObj == NULL)
                               3245                 :              4 :                 continue;
                               3246                 :              4 :             ftable = findTableByOid(cinfo->confrelid);
                               3247         [ +  - ]:              4 :             if (ftable == NULL ||
                               3248         [ -  + ]:              4 :                 ftable->dataObj == NULL)
 6258 tgl@sss.pgh.pa.us        3249                 :UBC           0 :                 continue;
                               3250                 :                : 
                               3251                 :                :             /*
                               3252                 :                :              * Okay, make referencing table's TABLE_DATA object depend on the
                               3253                 :                :              * referenced table's TABLE_DATA object.
                               3254                 :                :              */
 6258 tgl@sss.pgh.pa.us        3255                 :CBC           4 :             addObjectDependency(&cinfo->contable->dataObj->dobj,
                               3256                 :              4 :                                 ftable->dataObj->dobj.dumpId);
                               3257                 :                :         }
                               3258                 :                :     }
                               3259                 :              7 :     free(dobjs);
                               3260                 :              7 : }
                               3261                 :                : 
                               3262                 :                : 
                               3263                 :                : /*
                               3264                 :                :  * dumpDatabase:
                               3265                 :                :  *  dump the database definition
                               3266                 :                :  */
                               3267                 :                : static void
 3575                          3268                 :             87 : dumpDatabase(Archive *fout)
                               3269                 :                : {
                               3270                 :             87 :     DumpOptions *dopt = fout->dopt;
 8985 bruce@momjian.us         3271                 :             87 :     PQExpBuffer dbQry = createPQExpBuffer();
                               3272                 :             87 :     PQExpBuffer delQry = createPQExpBuffer();
                               3273                 :             87 :     PQExpBuffer creaQry = createPQExpBuffer();
 2835 tgl@sss.pgh.pa.us        3274                 :             87 :     PQExpBuffer labelq = createPQExpBuffer();
 5002 rhaas@postgresql.org     3275                 :             87 :     PGconn     *conn = GetConnection(fout);
                               3276                 :                :     PGresult   *res;
                               3277                 :                :     int         i_tableoid,
                               3278                 :                :                 i_oid,
                               3279                 :                :                 i_datname,
                               3280                 :                :                 i_datdba,
                               3281                 :                :                 i_encoding,
                               3282                 :                :                 i_datlocprovider,
                               3283                 :                :                 i_collate,
                               3284                 :                :                 i_ctype,
                               3285                 :                :                 i_datlocale,
                               3286                 :                :                 i_daticurules,
                               3287                 :                :                 i_frozenxid,
                               3288                 :                :                 i_minmxid,
                               3289                 :                :                 i_datacl,
                               3290                 :                :                 i_acldefault,
                               3291                 :                :                 i_datistemplate,
                               3292                 :                :                 i_datconnlimit,
                               3293                 :                :                 i_datcollversion,
                               3294                 :                :                 i_tablespace;
                               3295                 :                :     CatalogId   dbCatId;
                               3296                 :                :     DumpId      dbDumpId;
                               3297                 :                :     DumpableAcl dbdacl;
                               3298                 :                :     const char *datname,
                               3299                 :                :                *dba,
                               3300                 :                :                *encoding,
                               3301                 :                :                *datlocprovider,
                               3302                 :                :                *collate,
                               3303                 :                :                *ctype,
                               3304                 :                :                *locale,
                               3305                 :                :                *icurules,
                               3306                 :                :                *datistemplate,
                               3307                 :                :                *datconnlimit,
                               3308                 :                :                *tablespace;
                               3309                 :                :     uint32      frozenxid,
                               3310                 :                :                 minmxid;
                               3311                 :                :     char       *qdatname;
                               3312                 :                : 
 2401 peter@eisentraut.org     3313                 :             87 :     pg_log_info("saving database definition");
                               3314                 :                : 
                               3315                 :                :     /*
                               3316                 :                :      * Fetch the database-level properties for this database.
                               3317                 :                :      */
 1147 drowley@postgresql.o     3318                 :             87 :     appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
                               3319                 :                :                          "datdba, "
                               3320                 :                :                          "pg_encoding_to_char(encoding) AS encoding, "
                               3321                 :                :                          "datcollate, datctype, datfrozenxid, "
                               3322                 :                :                          "datacl, acldefault('d', datdba) AS acldefault, "
                               3323                 :                :                          "datistemplate, datconnlimit, ");
 1421 tgl@sss.pgh.pa.us        3324         [ +  - ]:             87 :     if (fout->remoteVersion >= 90300)
 1147 drowley@postgresql.o     3325                 :             87 :         appendPQExpBufferStr(dbQry, "datminmxid, ");
                               3326                 :                :     else
 1147 drowley@postgresql.o     3327                 :UBC           0 :         appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
  597 jdavis@postgresql.or     3328         [ +  - ]:CBC          87 :     if (fout->remoteVersion >= 170000)
                               3329                 :             87 :         appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
  597 jdavis@postgresql.or     3330         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 150000)
                               3331                 :              0 :         appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
                               3332                 :                :     else
                               3333                 :              0 :         appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
  964 peter@eisentraut.org     3334         [ +  - ]:CBC          87 :     if (fout->remoteVersion >= 160000)
                               3335                 :             87 :         appendPQExpBufferStr(dbQry, "daticurules, ");
                               3336                 :                :     else
  964 peter@eisentraut.org     3337                 :UBC           0 :         appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
 1147 drowley@postgresql.o     3338                 :CBC          87 :     appendPQExpBufferStr(dbQry,
                               3339                 :                :                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                               3340                 :                :                          "shobj_description(oid, 'pg_database') AS description "
                               3341                 :                :                          "FROM pg_database "
                               3342                 :                :                          "WHERE datname = current_database()");
                               3343                 :                : 
 5002 rhaas@postgresql.org     3344                 :             87 :     res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
                               3345                 :                : 
 7996 tgl@sss.pgh.pa.us        3346                 :             87 :     i_tableoid = PQfnumber(res, "tableoid");
                               3347                 :             87 :     i_oid = PQfnumber(res, "oid");
 2757 peter_e@gmx.net          3348                 :             87 :     i_datname = PQfnumber(res, "datname");
 1396 tgl@sss.pgh.pa.us        3349                 :             87 :     i_datdba = PQfnumber(res, "datdba");
 8659                          3350                 :             87 :     i_encoding = PQfnumber(res, "encoding");
 1320 peter@eisentraut.org     3351                 :             87 :     i_datlocprovider = PQfnumber(res, "datlocprovider");
 6242 heikki.linnakangas@i     3352                 :             87 :     i_collate = PQfnumber(res, "datcollate");
                               3353                 :             87 :     i_ctype = PQfnumber(res, "datctype");
  597 jdavis@postgresql.or     3354                 :             87 :     i_datlocale = PQfnumber(res, "datlocale");
  964 peter@eisentraut.org     3355                 :             87 :     i_daticurules = PQfnumber(res, "daticurules");
 6095 bruce@momjian.us         3356                 :             87 :     i_frozenxid = PQfnumber(res, "datfrozenxid");
 4135                          3357                 :             87 :     i_minmxid = PQfnumber(res, "datminmxid");
 2835 tgl@sss.pgh.pa.us        3358                 :             87 :     i_datacl = PQfnumber(res, "datacl");
 1421                          3359                 :             87 :     i_acldefault = PQfnumber(res, "acldefault");
 2835                          3360                 :             87 :     i_datistemplate = PQfnumber(res, "datistemplate");
                               3361                 :             87 :     i_datconnlimit = PQfnumber(res, "datconnlimit");
 1351 peter@eisentraut.org     3362                 :             87 :     i_datcollversion = PQfnumber(res, "datcollversion");
 7801 tgl@sss.pgh.pa.us        3363                 :             87 :     i_tablespace = PQfnumber(res, "tablespace");
                               3364                 :                : 
 7996                          3365                 :             87 :     dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
                               3366                 :             87 :     dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
 2757 peter_e@gmx.net          3367                 :             87 :     datname = PQgetvalue(res, 0, i_datname);
 1396 tgl@sss.pgh.pa.us        3368                 :             87 :     dba = getRoleName(PQgetvalue(res, 0, i_datdba));
 8659                          3369                 :             87 :     encoding = PQgetvalue(res, 0, i_encoding);
 1320 peter@eisentraut.org     3370                 :             87 :     datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
 6243 heikki.linnakangas@i     3371                 :             87 :     collate = PQgetvalue(res, 0, i_collate);
                               3372                 :             87 :     ctype = PQgetvalue(res, 0, i_ctype);
  597 jdavis@postgresql.or     3373         [ +  + ]:             87 :     if (!PQgetisnull(res, 0, i_datlocale))
                               3374                 :             14 :         locale = PQgetvalue(res, 0, i_datlocale);
                               3375                 :                :     else
                               3376                 :             73 :         locale = NULL;
  964 peter@eisentraut.org     3377         [ -  + ]:             87 :     if (!PQgetisnull(res, 0, i_daticurules))
  964 peter@eisentraut.org     3378                 :UBC           0 :         icurules = PQgetvalue(res, 0, i_daticurules);
                               3379                 :                :     else
  964 peter@eisentraut.org     3380                 :CBC          87 :         icurules = NULL;
 6095 bruce@momjian.us         3381                 :             87 :     frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
 4135                          3382                 :             87 :     minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
 1421 tgl@sss.pgh.pa.us        3383                 :             87 :     dbdacl.acl = PQgetvalue(res, 0, i_datacl);
                               3384                 :             87 :     dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
 2835                          3385                 :             87 :     datistemplate = PQgetvalue(res, 0, i_datistemplate);
                               3386                 :             87 :     datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
 7801                          3387                 :             87 :     tablespace = PQgetvalue(res, 0, i_tablespace);
                               3388                 :                : 
 2757 peter_e@gmx.net          3389                 :             87 :     qdatname = pg_strdup(fmtId(datname));
                               3390                 :                : 
                               3391                 :                :     /*
                               3392                 :                :      * Prepare the CREATE DATABASE command.  We must specify OID (if we want
                               3393                 :                :      * to preserve that), as well as the encoding, locale, and tablespace
                               3394                 :                :      * since those can't be altered later.  Other DB properties are left to
                               3395                 :                :      * the DATABASE PROPERTIES entry, so that they can be applied after
                               3396                 :                :      * reconnecting to the target DB.
                               3397                 :                :      *
                               3398                 :                :      * For binary upgrade, we use the FILE_COPY strategy because testing has
                               3399                 :                :      * shown it to be faster.  When the server is in binary upgrade mode, it
                               3400                 :                :      * will also skip the checkpoints this strategy ordinarily performs.
                               3401                 :                :      */
 1372 rhaas@postgresql.org     3402         [ +  + ]:             87 :     if (dopt->binary_upgrade)
                               3403                 :                :     {
  476 nathan@postgresql.or     3404                 :             35 :         appendPQExpBuffer(creaQry,
                               3405                 :                :                           "CREATE DATABASE %s WITH TEMPLATE = template0 "
                               3406                 :                :                           "OID = %u STRATEGY = FILE_COPY",
                               3407                 :                :                           qdatname, dbCatId.oid);
                               3408                 :                :     }
                               3409                 :                :     else
                               3410                 :                :     {
 1372 rhaas@postgresql.org     3411                 :             52 :         appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
                               3412                 :                :                           qdatname);
                               3413                 :                :     }
 8346 tgl@sss.pgh.pa.us        3414         [ +  - ]:             87 :     if (strlen(encoding) > 0)
                               3415                 :                :     {
 4361 heikki.linnakangas@i     3416                 :             87 :         appendPQExpBufferStr(creaQry, " ENCODING = ");
 5012 rhaas@postgresql.org     3417                 :             87 :         appendStringLiteralAH(creaQry, encoding, fout);
                               3418                 :                :     }
                               3419                 :                : 
 1320 peter@eisentraut.org     3420                 :             87 :     appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
  593 jdavis@postgresql.or     3421         [ +  + ]:             87 :     if (datlocprovider[0] == 'b')
                               3422                 :             14 :         appendPQExpBufferStr(creaQry, "builtin");
                               3423         [ +  - ]:             73 :     else if (datlocprovider[0] == 'c')
 1320 peter@eisentraut.org     3424                 :             73 :         appendPQExpBufferStr(creaQry, "libc");
 1320 peter@eisentraut.org     3425         [ #  # ]:UBC           0 :     else if (datlocprovider[0] == 'i')
                               3426                 :              0 :         appendPQExpBufferStr(creaQry, "icu");
                               3427                 :                :     else
 1298 tgl@sss.pgh.pa.us        3428                 :              0 :         pg_fatal("unrecognized locale provider: %s",
                               3429                 :                :                  datlocprovider);
                               3430                 :                : 
 2288 peter@eisentraut.org     3431   [ +  -  +  - ]:CBC          87 :     if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
                               3432                 :                :     {
                               3433                 :             87 :         appendPQExpBufferStr(creaQry, " LOCALE = ");
 5012 rhaas@postgresql.org     3434                 :             87 :         appendStringLiteralAH(creaQry, collate, fout);
                               3435                 :                :     }
                               3436                 :                :     else
                               3437                 :                :     {
 2288 peter@eisentraut.org     3438         [ #  # ]:UBC           0 :         if (strlen(collate) > 0)
                               3439                 :                :         {
                               3440                 :              0 :             appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
                               3441                 :              0 :             appendStringLiteralAH(creaQry, collate, fout);
                               3442                 :                :         }
                               3443         [ #  # ]:              0 :         if (strlen(ctype) > 0)
                               3444                 :                :         {
                               3445                 :              0 :             appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
                               3446                 :              0 :             appendStringLiteralAH(creaQry, ctype, fout);
                               3447                 :                :         }
                               3448                 :                :     }
  597 jdavis@postgresql.or     3449         [ +  + ]:CBC          87 :     if (locale)
                               3450                 :                :     {
  593                          3451         [ +  - ]:             14 :         if (datlocprovider[0] == 'b')
                               3452                 :             14 :             appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
                               3453                 :                :         else
  593 jdavis@postgresql.or     3454                 :UBC           0 :             appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
                               3455                 :                : 
  597 jdavis@postgresql.or     3456                 :CBC          14 :         appendStringLiteralAH(creaQry, locale, fout);
                               3457                 :                :     }
                               3458                 :                : 
  964 peter@eisentraut.org     3459         [ -  + ]:             87 :     if (icurules)
                               3460                 :                :     {
  964 peter@eisentraut.org     3461                 :UBC           0 :         appendPQExpBufferStr(creaQry, " ICU_RULES = ");
                               3462                 :              0 :         appendStringLiteralAH(creaQry, icurules, fout);
                               3463                 :                :     }
                               3464                 :                : 
                               3465                 :                :     /*
                               3466                 :                :      * For binary upgrade, carry over the collation version.  For normal
                               3467                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                               3468                 :                :      */
 1351 peter@eisentraut.org     3469         [ +  + ]:CBC          87 :     if (dopt->binary_upgrade)
                               3470                 :                :     {
                               3471         [ +  + ]:             35 :         if (!PQgetisnull(res, 0, i_datcollversion))
                               3472                 :                :         {
                               3473                 :              6 :             appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
                               3474                 :              6 :             appendStringLiteralAH(creaQry,
                               3475                 :                :                                   PQgetvalue(res, 0, i_datcollversion),
                               3476                 :                :                                   fout);
                               3477                 :                :         }
                               3478                 :                :     }
                               3479                 :                : 
                               3480                 :                :     /*
                               3481                 :                :      * Note: looking at dopt->outputNoTablespaces here is completely the wrong
                               3482                 :                :      * thing; the decision whether to specify a tablespace should be left till
                               3483                 :                :      * pg_restore, so that pg_restore --no-tablespaces applies.  Ideally we'd
                               3484                 :                :      * label the DATABASE entry with the tablespace and let the normal
                               3485                 :                :      * tablespace selection logic work ... but CREATE DATABASE doesn't pay
                               3486                 :                :      * attention to default_tablespace, so that won't work.
                               3487                 :                :      */
 3336 tgl@sss.pgh.pa.us        3488   [ +  -  +  + ]:             87 :     if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
 3336 tgl@sss.pgh.pa.us        3489         [ +  - ]:GBC           5 :         !dopt->outputNoTablespaces)
 7679                          3490                 :              5 :         appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                               3491                 :                :                           fmtId(tablespace));
 4361 heikki.linnakangas@i     3492                 :CBC          87 :     appendPQExpBufferStr(creaQry, ";\n");
                               3493                 :                : 
 8659 tgl@sss.pgh.pa.us        3494                 :             87 :     appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
                               3495                 :                :                       qdatname);
                               3496                 :                : 
 7996                          3497                 :             87 :     dbDumpId = createDumpId();
                               3498                 :                : 
 5012 rhaas@postgresql.org     3499                 :             87 :     ArchiveEntry(fout,
                               3500                 :                :                  dbCatId,       /* catalog ID */
                               3501                 :                :                  dbDumpId,      /* dump ID */
 2460 alvherre@alvh.no-ip.     3502                 :             87 :                  ARCHIVE_OPTS(.tag = datname,
                               3503                 :                :                               .owner = dba,
                               3504                 :                :                               .description = "DATABASE",
                               3505                 :                :                               .section = SECTION_PRE_DATA,
                               3506                 :                :                               .createStmt = creaQry->data,
                               3507                 :                :                               .dropStmt = delQry->data));
                               3508                 :                : 
                               3509                 :                :     /* Compute correct tag for archive entry */
 2835 tgl@sss.pgh.pa.us        3510                 :             87 :     appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
                               3511                 :                : 
                               3512                 :                :     /* Dump DB comment if any */
                               3513                 :                :     {
                               3514                 :                :         /*
                               3515                 :                :          * 8.2 and up keep comments on shared objects in a shared table, so we
                               3516                 :                :          * cannot use the dumpComment() code used for other database objects.
                               3517                 :                :          * Be careful that the ArchiveEntry parameters match that function.
                               3518                 :                :          */
                               3519                 :             87 :         char       *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
                               3520                 :                : 
 2832                          3521   [ +  -  +  +  :             87 :         if (comment && *comment && !dopt->no_comments)
                                              +  - ]
                               3522                 :                :         {
 2835                          3523                 :             42 :             resetPQExpBuffer(dbQry);
                               3524                 :                : 
                               3525                 :                :             /*
                               3526                 :                :              * Generates warning when loaded into a differently-named
                               3527                 :                :              * database.
                               3528                 :                :              */
                               3529                 :             42 :             appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
                               3530                 :             42 :             appendStringLiteralAH(dbQry, comment, fout);
                               3531                 :             42 :             appendPQExpBufferStr(dbQry, ";\n");
                               3532                 :                : 
                               3533                 :             42 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3534                 :             42 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3535                 :                :                                       .owner = dba,
                               3536                 :                :                                       .description = "COMMENT",
                               3537                 :                :                                       .section = SECTION_NONE,
                               3538                 :                :                                       .createStmt = dbQry->data,
                               3539                 :                :                                       .deps = &dbDumpId,
                               3540                 :                :                                       .nDeps = 1));
                               3541                 :                :         }
                               3542                 :                :     }
                               3543                 :                : 
                               3544                 :                :     /* Dump DB security label, if enabled */
 1413 tgl@sss.pgh.pa.us        3545         [ +  - ]:             87 :     if (!dopt->no_security_labels)
                               3546                 :                :     {
                               3547                 :                :         PGresult   *shres;
                               3548                 :                :         PQExpBuffer seclabelQry;
                               3549                 :                : 
 2835                          3550                 :             87 :         seclabelQry = createPQExpBuffer();
                               3551                 :                : 
 1889 peter@eisentraut.org     3552                 :             87 :         buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
 2835 tgl@sss.pgh.pa.us        3553                 :             87 :         shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
                               3554                 :             87 :         resetPQExpBuffer(seclabelQry);
                               3555                 :             87 :         emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
                               3556         [ -  + ]:             87 :         if (seclabelQry->len > 0)
 2835 tgl@sss.pgh.pa.us        3557                 :UBC           0 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3558                 :              0 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3559                 :                :                                       .owner = dba,
                               3560                 :                :                                       .description = "SECURITY LABEL",
                               3561                 :                :                                       .section = SECTION_NONE,
                               3562                 :                :                                       .createStmt = seclabelQry->data,
                               3563                 :                :                                       .deps = &dbDumpId,
                               3564                 :                :                                       .nDeps = 1));
 2835 tgl@sss.pgh.pa.us        3565                 :CBC          87 :         destroyPQExpBuffer(seclabelQry);
                               3566                 :             87 :         PQclear(shres);
                               3567                 :                :     }
                               3568                 :                : 
                               3569                 :                :     /*
                               3570                 :                :      * Dump ACL if any.  Note that we do not support initial privileges
                               3571                 :                :      * (pg_init_privs) on databases.
                               3572                 :                :      */
 1421                          3573                 :             87 :     dbdacl.privtype = 0;
                               3574                 :             87 :     dbdacl.initprivs = NULL;
                               3575                 :                : 
 1934                          3576                 :             87 :     dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
                               3577                 :                :             qdatname, NULL, NULL,
                               3578                 :                :             NULL, dba, &dbdacl);
                               3579                 :                : 
                               3580                 :                :     /*
                               3581                 :                :      * Now construct a DATABASE PROPERTIES archive entry to restore any
                               3582                 :                :      * non-default database-level properties.  (The reason this must be
                               3583                 :                :      * separate is that we cannot put any additional commands into the TOC
                               3584                 :                :      * entry that has CREATE DATABASE.  pg_restore would execute such a group
                               3585                 :                :      * in an implicit transaction block, and the backend won't allow CREATE
                               3586                 :                :      * DATABASE in that context.)
                               3587                 :                :      */
 2835                          3588                 :             87 :     resetPQExpBuffer(creaQry);
                               3589                 :             87 :     resetPQExpBuffer(delQry);
                               3590                 :                : 
                               3591   [ +  -  -  + ]:             87 :     if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
 2835 tgl@sss.pgh.pa.us        3592                 :UBC           0 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
                               3593                 :                :                           qdatname, datconnlimit);
                               3594                 :                : 
 2835 tgl@sss.pgh.pa.us        3595         [ +  + ]:CBC          87 :     if (strcmp(datistemplate, "t") == 0)
                               3596                 :                :     {
                               3597                 :             10 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
                               3598                 :                :                           qdatname);
                               3599                 :                : 
                               3600                 :                :         /*
                               3601                 :                :          * The backend won't accept DROP DATABASE on a template database.  We
                               3602                 :                :          * can deal with that by removing the template marking before the DROP
                               3603                 :                :          * gets issued.  We'd prefer to use ALTER DATABASE IF EXISTS here, but
                               3604                 :                :          * since no such command is currently supported, fake it with a direct
                               3605                 :                :          * UPDATE on pg_database.
                               3606                 :                :          */
                               3607                 :             10 :         appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
                               3608                 :                :                              "SET datistemplate = false WHERE datname = ");
                               3609                 :             10 :         appendStringLiteralAH(delQry, datname, fout);
                               3610                 :             10 :         appendPQExpBufferStr(delQry, ";\n");
                               3611                 :                :     }
                               3612                 :                : 
                               3613                 :                :     /*
                               3614                 :                :      * We do not restore pg_database.dathasloginevt because it is set
                               3615                 :                :      * automatically on login event trigger creation.
                               3616                 :                :      */
                               3617                 :                : 
                               3618                 :                :     /* Add database-specific SET options */
                               3619                 :             87 :     dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
                               3620                 :                : 
                               3621                 :                :     /*
                               3622                 :                :      * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
                               3623                 :                :      * entry, too, for lack of a better place.
                               3624                 :                :      */
                               3625         [ +  + ]:             87 :     if (dopt->binary_upgrade)
                               3626                 :                :     {
                               3627                 :             35 :         appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
                               3628                 :             35 :         appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
                               3629                 :                :                           "SET datfrozenxid = '%u', datminmxid = '%u'\n"
                               3630                 :                :                           "WHERE datname = ",
                               3631                 :                :                           frozenxid, minmxid);
                               3632                 :             35 :         appendStringLiteralAH(creaQry, datname, fout);
                               3633                 :             35 :         appendPQExpBufferStr(creaQry, ";\n");
                               3634                 :                :     }
                               3635                 :                : 
                               3636         [ +  + ]:             87 :     if (creaQry->len > 0)
                               3637                 :             39 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3638                 :             39 :                      ARCHIVE_OPTS(.tag = datname,
                               3639                 :                :                                   .owner = dba,
                               3640                 :                :                                   .description = "DATABASE PROPERTIES",
                               3641                 :                :                                   .section = SECTION_PRE_DATA,
                               3642                 :                :                                   .createStmt = creaQry->data,
                               3643                 :                :                                   .dropStmt = delQry->data,
                               3644                 :                :                                   .deps = &dbDumpId));
                               3645                 :                : 
                               3646                 :                :     /*
                               3647                 :                :      * pg_largeobject comes from the old system intact, so set its
                               3648                 :                :      * relfrozenxids, relminmxids and relfilenode.
                               3649                 :                :      *
                               3650                 :                :      * pg_largeobject_metadata also comes from the old system intact for
                               3651                 :                :      * upgrades from v16 and newer, so set its relfrozenxids, relminmxids, and
                               3652                 :                :      * relfilenode, too.  pg_upgrade can't copy/link the files from older
                               3653                 :                :      * versions because aclitem (needed by pg_largeobject_metadata.lomacl)
                               3654                 :                :      * changed its storage format in v16.
                               3655                 :                :      */
 4031                          3656         [ +  + ]:             87 :     if (dopt->binary_upgrade)
                               3657                 :                :     {
                               3658                 :                :         PGresult   *lo_res;
 5943 bruce@momjian.us         3659                 :             35 :         PQExpBuffer loFrozenQry = createPQExpBuffer();
                               3660                 :             35 :         PQExpBuffer loOutQry = createPQExpBuffer();
   49 nathan@postgresql.or     3661                 :GNC          35 :         PQExpBuffer lomOutQry = createPQExpBuffer();
 1186 rhaas@postgresql.org     3662                 :CBC          35 :         PQExpBuffer loHorizonQry = createPQExpBuffer();
   49 nathan@postgresql.or     3663                 :GNC          35 :         PQExpBuffer lomHorizonQry = createPQExpBuffer();
                               3664                 :                :         int         ii_relfrozenxid,
                               3665                 :                :                     ii_relfilenode,
                               3666                 :                :                     ii_oid,
                               3667                 :                :                     ii_relminmxid;
                               3668                 :                : 
 4135 bruce@momjian.us         3669         [ +  - ]:CBC          35 :         if (fout->remoteVersion >= 90300)
 1207 rhaas@postgresql.org     3670                 :             35 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
                               3671                 :                :                               "FROM pg_catalog.pg_class\n"
                               3672                 :                :                               "WHERE oid IN (%u, %u, %u, %u);\n",
                               3673                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId,
                               3674                 :                :                               LargeObjectMetadataRelationId, LargeObjectMetadataOidIndexId);
                               3675                 :                :         else
 1207 rhaas@postgresql.org     3676                 :UBC           0 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
                               3677                 :                :                               "FROM pg_catalog.pg_class\n"
                               3678                 :                :                               "WHERE oid IN (%u, %u);\n",
                               3679                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId);
                               3680                 :                : 
 1207 rhaas@postgresql.org     3681                 :CBC          35 :         lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
                               3682                 :                : 
 1164 drowley@postgresql.o     3683                 :             35 :         ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
                               3684                 :             35 :         ii_relminmxid = PQfnumber(lo_res, "relminmxid");
                               3685                 :             35 :         ii_relfilenode = PQfnumber(lo_res, "relfilenode");
                               3686                 :             35 :         ii_oid = PQfnumber(lo_res, "oid");
                               3687                 :                : 
 1186 rhaas@postgresql.org     3688                 :             35 :         appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
   49 nathan@postgresql.or     3689                 :GNC          35 :         appendPQExpBufferStr(lomHorizonQry, "\n-- For binary upgrade, set pg_largeobject_metadata relfrozenxid and relminmxid\n");
 1186 rhaas@postgresql.org     3690                 :CBC          35 :         appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
   49 nathan@postgresql.or     3691                 :GNC          35 :         appendPQExpBufferStr(lomOutQry, "\n-- For binary upgrade, preserve pg_largeobject_metadata and index relfilenodes\n");
 1207 rhaas@postgresql.org     3692         [ +  + ]:CBC         175 :         for (int i = 0; i < PQntuples(lo_res); ++i)
                               3693                 :                :         {
                               3694                 :                :             Oid         oid;
                               3695                 :                :             RelFileNumber relfilenumber;
                               3696                 :                :             PQExpBuffer horizonQry;
                               3697                 :                :             PQExpBuffer outQry;
                               3698                 :                : 
   49 nathan@postgresql.or     3699                 :GNC         140 :             oid = atooid(PQgetvalue(lo_res, i, ii_oid));
                               3700                 :            140 :             relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
                               3701                 :                : 
                               3702   [ +  +  +  + ]:            140 :             if (oid == LargeObjectRelationId ||
                               3703                 :                :                 oid == LargeObjectLOidPNIndexId)
                               3704                 :                :             {
                               3705                 :             70 :                 horizonQry = loHorizonQry;
                               3706                 :             70 :                 outQry = loOutQry;
                               3707                 :                :             }
                               3708                 :                :             else
                               3709                 :                :             {
                               3710                 :             70 :                 horizonQry = lomHorizonQry;
                               3711                 :             70 :                 outQry = lomOutQry;
                               3712                 :                :             }
                               3713                 :                : 
                               3714                 :            140 :             appendPQExpBuffer(horizonQry, "UPDATE pg_catalog.pg_class\n"
                               3715                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                               3716                 :                :                               "WHERE oid = %u;\n",
 1164 drowley@postgresql.o     3717                 :CBC         140 :                               atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
                               3718                 :            140 :                               atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
                               3719                 :            140 :                               atooid(PQgetvalue(lo_res, i, ii_oid)));
                               3720                 :                : 
   49 nathan@postgresql.or     3721   [ +  +  +  + ]:GNC         140 :             if (oid == LargeObjectRelationId ||
                               3722                 :                :                 oid == LargeObjectMetadataRelationId)
                               3723                 :             70 :                 appendPQExpBuffer(outQry,
                               3724                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               3725                 :                :                                   relfilenumber);
                               3726   [ +  +  +  - ]:             70 :             else if (oid == LargeObjectLOidPNIndexId ||
                               3727                 :                :                      oid == LargeObjectMetadataOidIndexId)
                               3728                 :             70 :                 appendPQExpBuffer(outQry,
                               3729                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               3730                 :                :                                   relfilenumber);
                               3731                 :                :         }
                               3732                 :                : 
 1186 rhaas@postgresql.org     3733                 :CBC          35 :         appendPQExpBufferStr(loOutQry,
                               3734                 :                :                              "TRUNCATE pg_catalog.pg_largeobject;\n");
   49 nathan@postgresql.or     3735                 :GNC          35 :         appendPQExpBufferStr(lomOutQry,
                               3736                 :                :                              "TRUNCATE pg_catalog.pg_largeobject_metadata;\n");
                               3737                 :                : 
 1186 rhaas@postgresql.org     3738                 :CBC          35 :         appendPQExpBufferStr(loOutQry, loHorizonQry->data);
   49 nathan@postgresql.or     3739                 :GNC          35 :         appendPQExpBufferStr(lomOutQry, lomHorizonQry->data);
                               3740                 :                : 
 5012 rhaas@postgresql.org     3741                 :CBC          35 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3742                 :             35 :                      ARCHIVE_OPTS(.tag = "pg_largeobject",
                               3743                 :                :                                   .description = "pg_largeobject",
                               3744                 :                :                                   .section = SECTION_PRE_DATA,
                               3745                 :                :                                   .createStmt = loOutQry->data));
                               3746                 :                : 
   49 nathan@postgresql.or     3747         [ +  - ]:GNC          35 :         if (fout->remoteVersion >= 160000)
                               3748                 :             35 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
                               3749                 :             35 :                          ARCHIVE_OPTS(.tag = "pg_largeobject_metadata",
                               3750                 :                :                                       .description = "pg_largeobject_metadata",
                               3751                 :                :                                       .section = SECTION_PRE_DATA,
                               3752                 :                :                                       .createStmt = lomOutQry->data));
                               3753                 :                : 
 5943 bruce@momjian.us         3754                 :CBC          35 :         PQclear(lo_res);
                               3755                 :                : 
                               3756                 :             35 :         destroyPQExpBuffer(loFrozenQry);
 1186 rhaas@postgresql.org     3757                 :             35 :         destroyPQExpBuffer(loHorizonQry);
   49 nathan@postgresql.or     3758                 :GNC          35 :         destroyPQExpBuffer(lomHorizonQry);
 5943 bruce@momjian.us         3759                 :CBC          35 :         destroyPQExpBuffer(loOutQry);
   49 nathan@postgresql.or     3760                 :GNC          35 :         destroyPQExpBuffer(lomOutQry);
                               3761                 :                :     }
                               3762                 :                : 
 3935 andres@anarazel.de       3763                 :CBC          87 :     PQclear(res);
                               3764                 :                : 
 2835 tgl@sss.pgh.pa.us        3765                 :             87 :     free(qdatname);
 8851                          3766                 :             87 :     destroyPQExpBuffer(dbQry);
                               3767                 :             87 :     destroyPQExpBuffer(delQry);
                               3768                 :             87 :     destroyPQExpBuffer(creaQry);
 2835                          3769                 :             87 :     destroyPQExpBuffer(labelq);
 9218 pjw@rhyme.com.au         3770                 :             87 : }
                               3771                 :                : 
                               3772                 :                : /*
                               3773                 :                :  * Collect any database-specific or role-and-database-specific SET options
                               3774                 :                :  * for this database, and append them to outbuf.
                               3775                 :                :  */
                               3776                 :                : static void
 2835 tgl@sss.pgh.pa.us        3777                 :             87 : dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                               3778                 :                :                    const char *dbname, Oid dboid)
                               3779                 :                : {
                               3780                 :             87 :     PGconn     *conn = GetConnection(AH);
                               3781                 :             87 :     PQExpBuffer buf = createPQExpBuffer();
                               3782                 :                :     PGresult   *res;
                               3783                 :                : 
                               3784                 :                :     /* First collect database-specific options */
  894 akorotkov@postgresql     3785                 :             87 :     printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
                               3786                 :                :                       "WHERE setrole = 0 AND setdatabase = '%u'::oid",
                               3787                 :                :                       dboid);
                               3788                 :                : 
 1413 tgl@sss.pgh.pa.us        3789                 :             87 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3790                 :                : 
                               3791         [ +  + ]:            117 :     for (int i = 0; i < PQntuples(res); i++)
  894 akorotkov@postgresql     3792                 :             30 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
                               3793                 :                :                                "DATABASE", dbname, NULL, NULL,
                               3794                 :                :                                outbuf);
                               3795                 :                : 
 1413 tgl@sss.pgh.pa.us        3796                 :             87 :     PQclear(res);
                               3797                 :                : 
                               3798                 :                :     /* Now look for role-and-database-specific options */
  894 akorotkov@postgresql     3799                 :             87 :     printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
                               3800                 :                :                       "FROM pg_db_role_setting s, pg_roles r "
                               3801                 :                :                       "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
                               3802                 :                :                       dboid);
                               3803                 :                : 
 1413 tgl@sss.pgh.pa.us        3804                 :             87 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3805                 :                : 
                               3806         [ -  + ]:             87 :     for (int i = 0; i < PQntuples(res); i++)
  894 akorotkov@postgresql     3807                 :UBC           0 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 1),
 1413 tgl@sss.pgh.pa.us        3808                 :              0 :                                "ROLE", PQgetvalue(res, i, 0),
                               3809                 :                :                                "DATABASE", dbname,
                               3810                 :                :                                outbuf);
                               3811                 :                : 
 1413 tgl@sss.pgh.pa.us        3812                 :CBC          87 :     PQclear(res);
                               3813                 :                : 
 2835                          3814                 :             87 :     destroyPQExpBuffer(buf);
                               3815                 :             87 : }
                               3816                 :                : 
                               3817                 :                : /*
                               3818                 :                :  * dumpEncoding: put the correct encoding into the archive
                               3819                 :                :  */
                               3820                 :                : static void
 7916                          3821                 :            189 : dumpEncoding(Archive *AH)
                               3822                 :                : {
 7092                          3823                 :            189 :     const char *encname = pg_encoding_to_char(AH->encoding);
                               3824                 :            189 :     PQExpBuffer qry = createPQExpBuffer();
                               3825                 :                : 
 2401 peter@eisentraut.org     3826                 :            189 :     pg_log_info("saving encoding = %s", encname);
                               3827                 :                : 
 4361 heikki.linnakangas@i     3828                 :            189 :     appendPQExpBufferStr(qry, "SET client_encoding = ");
 7092 tgl@sss.pgh.pa.us        3829                 :            189 :     appendStringLiteralAH(qry, encname, AH);
 4361 heikki.linnakangas@i     3830                 :            189 :     appendPQExpBufferStr(qry, ";\n");
                               3831                 :                : 
 7916 tgl@sss.pgh.pa.us        3832                 :            189 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3833                 :            189 :                  ARCHIVE_OPTS(.tag = "ENCODING",
                               3834                 :                :                               .description = "ENCODING",
                               3835                 :                :                               .section = SECTION_PRE_DATA,
                               3836                 :                :                               .createStmt = qry->data));
                               3837                 :                : 
 7916 tgl@sss.pgh.pa.us        3838                 :            189 :     destroyPQExpBuffer(qry);
                               3839                 :            189 : }
                               3840                 :                : 
                               3841                 :                : 
                               3842                 :                : /*
                               3843                 :                :  * dumpStdStrings: put the correct escape string behavior into the archive
                               3844                 :                :  */
                               3845                 :                : static void
 7094 bruce@momjian.us         3846                 :            189 : dumpStdStrings(Archive *AH)
                               3847                 :                : {
 7092 tgl@sss.pgh.pa.us        3848         [ +  - ]:            189 :     const char *stdstrings = AH->std_strings ? "on" : "off";
                               3849                 :            189 :     PQExpBuffer qry = createPQExpBuffer();
                               3850                 :                : 
  528 peter@eisentraut.org     3851                 :            189 :     pg_log_info("saving \"standard_conforming_strings = %s\"",
                               3852                 :                :                 stdstrings);
                               3853                 :                : 
 7092 tgl@sss.pgh.pa.us        3854                 :            189 :     appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
                               3855                 :                :                       stdstrings);
                               3856                 :                : 
 7094 bruce@momjian.us         3857                 :            189 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3858                 :            189 :                  ARCHIVE_OPTS(.tag = "STDSTRINGS",
                               3859                 :                :                               .description = "STDSTRINGS",
                               3860                 :                :                               .section = SECTION_PRE_DATA,
                               3861                 :                :                               .createStmt = qry->data));
                               3862                 :                : 
 7094 bruce@momjian.us         3863                 :            189 :     destroyPQExpBuffer(qry);
                               3864                 :            189 : }
                               3865                 :                : 
                               3866                 :                : /*
                               3867                 :                :  * dumpSearchPath: record the active search_path in the archive
                               3868                 :                :  */
                               3869                 :                : static void
 2800 tgl@sss.pgh.pa.us        3870                 :            189 : dumpSearchPath(Archive *AH)
                               3871                 :                : {
                               3872                 :            189 :     PQExpBuffer qry = createPQExpBuffer();
                               3873                 :            189 :     PQExpBuffer path = createPQExpBuffer();
                               3874                 :                :     PGresult   *res;
                               3875                 :            189 :     char      **schemanames = NULL;
                               3876                 :            189 :     int         nschemanames = 0;
                               3877                 :                :     int         i;
                               3878                 :                : 
                               3879                 :                :     /*
                               3880                 :                :      * We use the result of current_schemas(), not the search_path GUC,
                               3881                 :                :      * because that might contain wildcards such as "$user", which won't
                               3882                 :                :      * necessarily have the same value during restore.  Also, this way avoids
                               3883                 :                :      * listing schemas that may appear in search_path but not actually exist,
                               3884                 :                :      * which seems like a prudent exclusion.
                               3885                 :                :      */
                               3886                 :            189 :     res = ExecuteSqlQueryForSingleRow(AH,
                               3887                 :                :                                       "SELECT pg_catalog.current_schemas(false)");
                               3888                 :                : 
                               3889         [ -  + ]:            189 :     if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
 1298 tgl@sss.pgh.pa.us        3890                 :UBC           0 :         pg_fatal("could not parse result of current_schemas()");
                               3891                 :                : 
                               3892                 :                :     /*
                               3893                 :                :      * We use set_config(), not a simple "SET search_path" command, because
                               3894                 :                :      * the latter has less-clean behavior if the search path is empty.  While
                               3895                 :                :      * that's likely to get fixed at some point, it seems like a good idea to
                               3896                 :                :      * be as backwards-compatible as possible in what we put into archives.
                               3897                 :                :      */
 2800 tgl@sss.pgh.pa.us        3898         [ -  + ]:CBC         189 :     for (i = 0; i < nschemanames; i++)
                               3899                 :                :     {
 2800 tgl@sss.pgh.pa.us        3900         [ #  # ]:UBC           0 :         if (i > 0)
                               3901                 :              0 :             appendPQExpBufferStr(path, ", ");
                               3902                 :              0 :         appendPQExpBufferStr(path, fmtId(schemanames[i]));
                               3903                 :                :     }
                               3904                 :                : 
 2800 tgl@sss.pgh.pa.us        3905                 :CBC         189 :     appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
                               3906                 :            189 :     appendStringLiteralAH(qry, path->data, AH);
                               3907                 :            189 :     appendPQExpBufferStr(qry, ", false);\n");
                               3908                 :                : 
  528 peter@eisentraut.org     3909                 :            189 :     pg_log_info("saving \"search_path = %s\"", path->data);
                               3910                 :                : 
 2800 tgl@sss.pgh.pa.us        3911                 :            189 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.     3912                 :            189 :                  ARCHIVE_OPTS(.tag = "SEARCHPATH",
                               3913                 :                :                               .description = "SEARCHPATH",
                               3914                 :                :                               .section = SECTION_PRE_DATA,
                               3915                 :                :                               .createStmt = qry->data));
                               3916                 :                : 
                               3917                 :                :     /* Also save it in AH->searchpath, in case we're doing plain text dump */
 2800 tgl@sss.pgh.pa.us        3918                 :            189 :     AH->searchpath = pg_strdup(qry->data);
                               3919                 :                : 
 1229 peter@eisentraut.org     3920                 :            189 :     free(schemanames);
 2800 tgl@sss.pgh.pa.us        3921                 :            189 :     PQclear(res);
                               3922                 :            189 :     destroyPQExpBuffer(qry);
                               3923                 :            189 :     destroyPQExpBuffer(path);
                               3924                 :            189 : }
                               3925                 :                : 
                               3926                 :                : 
                               3927                 :                : /*
                               3928                 :                :  * getLOs:
                               3929                 :                :  *  Collect schema-level data about large objects
                               3930                 :                :  */
                               3931                 :                : static void
 1057 peter@eisentraut.org     3932                 :            161 : getLOs(Archive *fout)
                               3933                 :                : {
 3491 sfrost@snowman.net       3934                 :            161 :     DumpOptions *dopt = fout->dopt;
 1057 peter@eisentraut.org     3935                 :            161 :     PQExpBuffer loQry = createPQExpBuffer();
                               3936                 :                :     PGresult   *res;
                               3937                 :                :     int         ntups;
                               3938                 :                :     int         i;
                               3939                 :                :     int         n;
                               3940                 :                :     int         i_oid;
                               3941                 :                :     int         i_lomowner;
                               3942                 :                :     int         i_lomacl;
                               3943                 :                :     int         i_acldefault;
                               3944                 :                : 
 2401                          3945                 :            161 :     pg_log_info("reading large objects");
                               3946                 :                : 
                               3947                 :                :     /*
                               3948                 :                :      * Fetch LO OIDs and owner/ACL data.  Order the data so that all the blobs
                               3949                 :                :      * with the same owner/ACL appear together.
                               3950                 :                :      */
 1057                          3951                 :            161 :     appendPQExpBufferStr(loQry,
                               3952                 :                :                          "SELECT oid, lomowner, lomacl, "
                               3953                 :                :                          "acldefault('L', lomowner) AS acldefault "
                               3954                 :                :                          "FROM pg_largeobject_metadata "
                               3955                 :                :                          "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
                               3956                 :                : 
                               3957                 :            161 :     res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
                               3958                 :                : 
 3491 sfrost@snowman.net       3959                 :            161 :     i_oid = PQfnumber(res, "oid");
 1396 tgl@sss.pgh.pa.us        3960                 :            161 :     i_lomowner = PQfnumber(res, "lomowner");
 3491 sfrost@snowman.net       3961                 :            161 :     i_lomacl = PQfnumber(res, "lomacl");
 1421 tgl@sss.pgh.pa.us        3962                 :            161 :     i_acldefault = PQfnumber(res, "acldefault");
                               3963                 :                : 
 5730                          3964                 :            161 :     ntups = PQntuples(res);
                               3965                 :                : 
                               3966                 :                :     /*
                               3967                 :                :      * Group the blobs into suitably-sized groups that have the same owner and
                               3968                 :                :      * ACL setting, and build a metadata and a data DumpableObject for each
                               3969                 :                :      * group.  (If we supported initprivs for blobs, we'd have to insist that
                               3970                 :                :      * groups also share initprivs settings, since the DumpableObject only has
                               3971                 :                :      * room for one.)  i is the index of the first tuple in the current group,
                               3972                 :                :      * and n is the number of tuples we include in the group.
                               3973                 :                :      */
  574                          3974         [ +  + ]:            254 :     for (i = 0; i < ntups; i += n)
                               3975                 :                :     {
                               3976                 :             93 :         Oid         thisoid = atooid(PQgetvalue(res, i, i_oid));
                               3977                 :             93 :         char       *thisowner = PQgetvalue(res, i, i_lomowner);
                               3978                 :             93 :         char       *thisacl = PQgetvalue(res, i, i_lomacl);
                               3979                 :                :         LoInfo     *loinfo;
                               3980                 :                :         DumpableObject *lodata;
                               3981                 :                :         char        namebuf[64];
                               3982                 :                : 
                               3983                 :                :         /* Scan to find first tuple not to be included in group */
                               3984                 :             93 :         n = 1;
                               3985   [ +  -  +  + ]:            108 :         while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
                               3986                 :                :         {
                               3987         [ +  + ]:             54 :             if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
                               3988         [ +  + ]:             49 :                 strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
                               3989                 :                :                 break;
                               3990                 :             15 :             n++;
                               3991                 :                :         }
                               3992                 :                : 
                               3993                 :                :         /* Build the metadata DumpableObject */
                               3994                 :             93 :         loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
                               3995                 :                : 
                               3996                 :             93 :         loinfo->dobj.objType = DO_LARGE_OBJECT;
                               3997                 :             93 :         loinfo->dobj.catId.tableoid = LargeObjectRelationId;
                               3998                 :             93 :         loinfo->dobj.catId.oid = thisoid;
                               3999                 :             93 :         AssignDumpId(&loinfo->dobj);
                               4000                 :                : 
                               4001         [ +  + ]:             93 :         if (n > 1)
                               4002                 :             10 :             snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
                               4003                 :             10 :                      atooid(PQgetvalue(res, i + n - 1, i_oid)));
                               4004                 :                :         else
                               4005                 :             83 :             snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
                               4006                 :             93 :         loinfo->dobj.name = pg_strdup(namebuf);
                               4007                 :             93 :         loinfo->dacl.acl = pg_strdup(thisacl);
                               4008                 :             93 :         loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               4009                 :             93 :         loinfo->dacl.privtype = 0;
                               4010                 :             93 :         loinfo->dacl.initprivs = NULL;
                               4011                 :             93 :         loinfo->rolname = getRoleName(thisowner);
                               4012                 :             93 :         loinfo->numlos = n;
                               4013                 :             93 :         loinfo->looids[0] = thisoid;
                               4014                 :                :         /* Collect OIDs of the remaining blobs in this group */
                               4015         [ +  + ]:            108 :         for (int k = 1; k < n; k++)
                               4016                 :                :         {
                               4017                 :                :             CatalogId   extraID;
                               4018                 :                : 
                               4019                 :             15 :             loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
                               4020                 :                : 
                               4021                 :                :             /* Make sure we can look up loinfo by any of the blobs' OIDs */
                               4022                 :             15 :             extraID.tableoid = LargeObjectRelationId;
                               4023                 :             15 :             extraID.oid = loinfo->looids[k];
                               4024                 :             15 :             recordAdditionalCatalogID(extraID, &loinfo->dobj);
                               4025                 :                :         }
                               4026                 :                : 
                               4027                 :                :         /* LOs have data */
                               4028                 :             93 :         loinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               4029                 :                : 
                               4030                 :                :         /* Mark whether LO group has a non-empty ACL */
 1421                          4031         [ +  + ]:             93 :         if (!PQgetisnull(res, i, i_lomacl))
  574                          4032                 :             39 :             loinfo->dobj.components |= DUMP_COMPONENT_ACL;
                               4033                 :                : 
                               4034                 :                :         /*
                               4035                 :                :          * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
                               4036                 :                :          * as it will be copied by pg_upgrade, which simply copies the
                               4037                 :                :          * pg_largeobject table. We *do* however dump out anything but the
                               4038                 :                :          * data, as pg_upgrade copies just pg_largeobject, but not
                               4039                 :                :          * pg_largeobject_metadata, after the dump is restored.  In versions
                               4040                 :                :          * before v12, this is done via proper large object commands.  In
                               4041                 :                :          * newer versions, we dump the content of pg_largeobject_metadata and
                               4042                 :                :          * any associated pg_shdepend rows, which is faster to restore.  (On
                               4043                 :                :          * <v12, pg_largeobject_metadata was created WITH OIDS, so the OID
                               4044                 :                :          * column is hidden and won't be dumped.)
                               4045                 :                :          */
 3157 sfrost@snowman.net       4046         [ +  + ]:             93 :         if (dopt->binary_upgrade)
                               4047                 :                :         {
  101 nathan@postgresql.or     4048         [ +  - ]:GNC          13 :             if (fout->remoteVersion >= 120000)
                               4049                 :                :             {
                               4050                 :                :                 /*
                               4051                 :                :                  * We should've saved pg_largeobject_metadata's dump ID before
                               4052                 :                :                  * this point.
                               4053                 :                :                  */
                               4054         [ -  + ]:             13 :                 Assert(lo_metadata_dumpId);
                               4055                 :                : 
                               4056                 :             13 :                 loinfo->dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL | DUMP_COMPONENT_DEFINITION);
                               4057                 :                : 
                               4058                 :                :                 /*
                               4059                 :                :                  * Mark the large object as dependent on
                               4060                 :                :                  * pg_largeobject_metadata so that any large object
                               4061                 :                :                  * comments/seclables are dumped after it.
                               4062                 :                :                  */
                               4063                 :             13 :                 loinfo->dobj.dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               4064                 :             13 :                 loinfo->dobj.dependencies[0] = lo_metadata_dumpId;
                               4065                 :             13 :                 loinfo->dobj.nDeps = loinfo->dobj.allocDeps = 1;
                               4066                 :                :             }
                               4067                 :                :             else
  101 nathan@postgresql.or     4068                 :UNC           0 :                 loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
                               4069                 :                :         }
                               4070                 :                : 
                               4071                 :                :         /*
                               4072                 :                :          * Create a "BLOBS" data item for the group, too. This is just a
                               4073                 :                :          * placeholder for sorting; it carries no data now.
                               4074                 :                :          */
 1057 peter@eisentraut.org     4075                 :CBC          93 :         lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
                               4076                 :             93 :         lodata->objType = DO_LARGE_OBJECT_DATA;
                               4077                 :             93 :         lodata->catId = nilCatalogId;
                               4078                 :             93 :         AssignDumpId(lodata);
  574 tgl@sss.pgh.pa.us        4079                 :             93 :         lodata->name = pg_strdup(namebuf);
 1057 peter@eisentraut.org     4080                 :             93 :         lodata->components |= DUMP_COMPONENT_DATA;
                               4081                 :                :         /* Set up explicit dependency from data to metadata */
  574 tgl@sss.pgh.pa.us        4082                 :             93 :         lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               4083                 :             93 :         lodata->dependencies[0] = loinfo->dobj.dumpId;
                               4084                 :             93 :         lodata->nDeps = lodata->allocDeps = 1;
                               4085                 :                :     }
                               4086                 :                : 
 7424                          4087                 :            161 :     PQclear(res);
 1057 peter@eisentraut.org     4088                 :            161 :     destroyPQExpBuffer(loQry);
 5730 tgl@sss.pgh.pa.us        4089                 :            161 : }
                               4090                 :                : 
                               4091                 :                : /*
                               4092                 :                :  * dumpLO
                               4093                 :                :  *
                               4094                 :                :  * dump the definition (metadata) of the given large object group
                               4095                 :                :  */
                               4096                 :                : static void
 1057 peter@eisentraut.org     4097                 :             87 : dumpLO(Archive *fout, const LoInfo *loinfo)
                               4098                 :                : {
 5722 bruce@momjian.us         4099                 :             87 :     PQExpBuffer cquery = createPQExpBuffer();
                               4100                 :                : 
                               4101                 :                :     /*
                               4102                 :                :      * The "definition" is just a newline-separated list of OIDs.  We need to
                               4103                 :                :      * put something into the dropStmt too, but it can just be a comment.
                               4104                 :                :      */
  574 tgl@sss.pgh.pa.us        4105         [ +  + ]:            189 :     for (int i = 0; i < loinfo->numlos; i++)
                               4106                 :            102 :         appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
                               4107                 :                : 
 1057 peter@eisentraut.org     4108         [ +  + ]:             87 :     if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4109                 :             80 :         ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
                               4110                 :             80 :                      ARCHIVE_OPTS(.tag = loinfo->dobj.name,
                               4111                 :                :                                   .owner = loinfo->rolname,
                               4112                 :                :                                   .description = "BLOB METADATA",
                               4113                 :                :                                   .section = SECTION_DATA,
                               4114                 :                :                                   .createStmt = cquery->data,
                               4115                 :                :                                   .dropStmt = "-- dummy"));
                               4116                 :                : 
                               4117                 :                :     /*
                               4118                 :                :      * Dump per-blob comments and seclabels if any.  We assume these are rare
                               4119                 :                :      * enough that it's okay to generate retail TOC entries for them.
                               4120                 :                :      */
  574 tgl@sss.pgh.pa.us        4121         [ +  + ]:             87 :     if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
                               4122                 :                :                              DUMP_COMPONENT_SECLABEL))
                               4123                 :                :     {
                               4124         [ +  + ]:            103 :         for (int i = 0; i < loinfo->numlos; i++)
                               4125                 :                :         {
                               4126                 :                :             CatalogId   catId;
                               4127                 :                :             char        namebuf[32];
                               4128                 :                : 
                               4129                 :                :             /* Build identifying info for this blob */
                               4130                 :             59 :             catId.tableoid = loinfo->dobj.catId.tableoid;
                               4131                 :             59 :             catId.oid = loinfo->looids[i];
                               4132                 :             59 :             snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
                               4133                 :                : 
                               4134         [ +  - ]:             59 :             if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                               4135                 :             59 :                 dumpComment(fout, "LARGE OBJECT", namebuf,
                               4136                 :             59 :                             NULL, loinfo->rolname,
                               4137                 :             59 :                             catId, 0, loinfo->dobj.dumpId);
                               4138                 :                : 
                               4139         [ +  + ]:             59 :             if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
  574 tgl@sss.pgh.pa.us        4140                 :GBC          10 :                 dumpSecLabel(fout, "LARGE OBJECT", namebuf,
                               4141                 :             10 :                              NULL, loinfo->rolname,
                               4142                 :             10 :                              catId, 0, loinfo->dobj.dumpId);
                               4143                 :                :         }
                               4144                 :                :     }
                               4145                 :                : 
                               4146                 :                :     /*
                               4147                 :                :      * Dump the ACLs if any (remember that all blobs in the group will have
                               4148                 :                :      * the same ACL).  If there's just one blob, dump a simple ACL entry; if
                               4149                 :                :      * there's more, make a "LARGE OBJECTS" entry that really contains only
                               4150                 :                :      * the ACL for the first blob.  _printTocEntry() will be cued by the tag
                               4151                 :                :      * string to emit a mutated version for each blob.
                               4152                 :                :      */
 1057 peter@eisentraut.org     4153         [ +  + ]:CBC          87 :     if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
                               4154                 :                :     {
                               4155                 :                :         char        namebuf[32];
                               4156                 :                : 
                               4157                 :                :         /* Build identifying info for the first blob */
  574 tgl@sss.pgh.pa.us        4158                 :             33 :         snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
                               4159                 :                : 
                               4160         [ -  + ]:             33 :         if (loinfo->numlos > 1)
                               4161                 :                :         {
                               4162                 :                :             char        tagbuf[64];
                               4163                 :                : 
  574 tgl@sss.pgh.pa.us        4164                 :UBC           0 :             snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
                               4165                 :              0 :                      loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
                               4166                 :                : 
                               4167                 :              0 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               4168                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               4169                 :              0 :                     tagbuf, loinfo->rolname, &loinfo->dacl);
                               4170                 :                :         }
                               4171                 :                :         else
                               4172                 :                :         {
  574 tgl@sss.pgh.pa.us        4173                 :CBC          33 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               4174                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               4175                 :             33 :                     NULL, loinfo->rolname, &loinfo->dacl);
                               4176                 :                :         }
                               4177                 :                :     }
                               4178                 :                : 
 5730                          4179                 :             87 :     destroyPQExpBuffer(cquery);
 7424                          4180                 :             87 : }
                               4181                 :                : 
                               4182                 :                : /*
                               4183                 :                :  * dumpLOs:
                               4184                 :                :  *  dump the data contents of the large objects in the given group
                               4185                 :                :  */
                               4186                 :                : static int
 1057 peter@eisentraut.org     4187                 :             76 : dumpLOs(Archive *fout, const void *arg)
                               4188                 :                : {
  574 tgl@sss.pgh.pa.us        4189                 :             76 :     const LoInfo *loinfo = (const LoInfo *) arg;
 5002 rhaas@postgresql.org     4190                 :             76 :     PGconn     *conn = GetConnection(fout);
                               4191                 :                :     char        buf[LOBBUFSIZE];
                               4192                 :                : 
  574 tgl@sss.pgh.pa.us        4193                 :             76 :     pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
                               4194                 :                : 
                               4195         [ +  + ]:            160 :     for (int i = 0; i < loinfo->numlos; i++)
                               4196                 :                :     {
                               4197                 :             84 :         Oid         loOid = loinfo->looids[i];
                               4198                 :                :         int         loFd;
                               4199                 :                :         int         cnt;
                               4200                 :                : 
                               4201                 :                :         /* Open the LO */
                               4202                 :             84 :         loFd = lo_open(conn, loOid, INV_READ);
                               4203         [ -  + ]:             84 :         if (loFd == -1)
  574 tgl@sss.pgh.pa.us        4204                 :UBC           0 :             pg_fatal("could not open large object %u: %s",
                               4205                 :                :                      loOid, PQerrorMessage(conn));
                               4206                 :                : 
  574 tgl@sss.pgh.pa.us        4207                 :CBC          84 :         StartLO(fout, loOid);
                               4208                 :                : 
                               4209                 :                :         /* Now read it in chunks, sending data to archive */
                               4210                 :                :         do
                               4211                 :                :         {
                               4212                 :            133 :             cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                               4213         [ -  + ]:            133 :             if (cnt < 0)
  574 tgl@sss.pgh.pa.us        4214                 :UBC           0 :                 pg_fatal("error reading large object %u: %s",
                               4215                 :                :                          loOid, PQerrorMessage(conn));
                               4216                 :                : 
  574 tgl@sss.pgh.pa.us        4217                 :CBC         133 :             WriteData(fout, buf, cnt);
                               4218         [ +  + ]:            133 :         } while (cnt > 0);
                               4219                 :                : 
                               4220                 :             84 :         lo_close(conn, loFd);
                               4221                 :                : 
                               4222                 :             84 :         EndLO(fout, loOid);
                               4223                 :                :     }
                               4224                 :                : 
 7424                          4225                 :             76 :     return 1;
                               4226                 :                : }
                               4227                 :                : 
                               4228                 :                : /*
                               4229                 :                :  * getPolicies
                               4230                 :                :  *    get information about all RLS policies on dumpable tables.
                               4231                 :                :  */
                               4232                 :                : void
 3987 sfrost@snowman.net       4233                 :            189 : getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                               4234                 :                : {
  225 tgl@sss.pgh.pa.us        4235                 :            189 :     DumpOptions *dopt = fout->dopt;
                               4236                 :                :     PQExpBuffer query;
                               4237                 :                :     PQExpBuffer tbloids;
                               4238                 :                :     PGresult   *res;
                               4239                 :                :     PolicyInfo *polinfo;
                               4240                 :                :     int         i_oid;
                               4241                 :                :     int         i_tableoid;
                               4242                 :                :     int         i_polrelid;
                               4243                 :                :     int         i_polname;
                               4244                 :                :     int         i_polcmd;
                               4245                 :                :     int         i_polpermissive;
                               4246                 :                :     int         i_polroles;
                               4247                 :                :     int         i_polqual;
                               4248                 :                :     int         i_polwithcheck;
                               4249                 :                :     int         i,
                               4250                 :                :                 j,
                               4251                 :                :                 ntups;
                               4252                 :                : 
                               4253                 :                :     /* No policies before 9.5 */
 4056 sfrost@snowman.net       4254         [ -  + ]:            189 :     if (fout->remoteVersion < 90500)
 4056 sfrost@snowman.net       4255                 :UBC           0 :         return;
                               4256                 :                : 
                               4257                 :                :     /* Skip if --no-policies was specified */
  225 tgl@sss.pgh.pa.us        4258         [ +  + ]:CBC         189 :     if (dopt->no_policies)
                               4259                 :              1 :         return;
                               4260                 :                : 
 4051 sfrost@snowman.net       4261                 :            188 :     query = createPQExpBuffer();
 1396 tgl@sss.pgh.pa.us        4262                 :            188 :     tbloids = createPQExpBuffer();
                               4263                 :                : 
                               4264                 :                :     /*
                               4265                 :                :      * Identify tables of interest, and check which ones have RLS enabled.
                               4266                 :                :      */
                               4267                 :            188 :     appendPQExpBufferChar(tbloids, '{');
 4056 sfrost@snowman.net       4268         [ +  + ]:          49560 :     for (i = 0; i < numTables; i++)
                               4269                 :                :     {
 4028 tgl@sss.pgh.pa.us        4270                 :          49372 :         TableInfo  *tbinfo = &tblinfo[i];
                               4271                 :                : 
                               4272                 :                :         /* Ignore row security on tables not to be dumped */
 3491 sfrost@snowman.net       4273         [ +  + ]:          49372 :         if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
 4056                          4274                 :          42506 :             continue;
                               4275                 :                : 
                               4276                 :                :         /* It can't have RLS or policies if it's not a table */
 1396 tgl@sss.pgh.pa.us        4277         [ +  + ]:           6866 :         if (tbinfo->relkind != RELKIND_RELATION &&
                               4278         [ +  + ]:           1939 :             tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
                               4279                 :           1353 :             continue;
                               4280                 :                : 
                               4281                 :                :         /* Add it to the list of table OIDs to be probed below */
                               4282         [ +  + ]:           5513 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               4283                 :           5389 :             appendPQExpBufferChar(tbloids, ',');
                               4284                 :           5513 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               4285                 :                : 
                               4286                 :                :         /* Is RLS enabled?  (That's separate from whether it has policies) */
 4051 sfrost@snowman.net       4287         [ +  + ]:           5513 :         if (tbinfo->rowsec)
                               4288                 :                :         {
 1421 tgl@sss.pgh.pa.us        4289                 :             53 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               4290                 :                : 
                               4291                 :                :             /*
                               4292                 :                :              * We represent RLS being enabled on a table by creating a
                               4293                 :                :              * PolicyInfo object with null polname.
                               4294                 :                :              *
                               4295                 :                :              * Note: use tableoid 0 so that this object won't be mistaken for
                               4296                 :                :              * something that pg_depend entries apply to.
                               4297                 :                :              */
 3987 sfrost@snowman.net       4298                 :             53 :             polinfo = pg_malloc(sizeof(PolicyInfo));
                               4299                 :             53 :             polinfo->dobj.objType = DO_POLICY;
                               4300                 :             53 :             polinfo->dobj.catId.tableoid = 0;
                               4301                 :             53 :             polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               4302                 :             53 :             AssignDumpId(&polinfo->dobj);
                               4303                 :             53 :             polinfo->dobj.namespace = tbinfo->dobj.namespace;
                               4304                 :             53 :             polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
                               4305                 :             53 :             polinfo->poltable = tbinfo;
                               4306                 :             53 :             polinfo->polname = NULL;
 3248                          4307                 :             53 :             polinfo->polcmd = '\0';
                               4308                 :             53 :             polinfo->polpermissive = 0;
 3987                          4309                 :             53 :             polinfo->polroles = NULL;
                               4310                 :             53 :             polinfo->polqual = NULL;
                               4311                 :             53 :             polinfo->polwithcheck = NULL;
                               4312                 :                :         }
                               4313                 :                :     }
 1396 tgl@sss.pgh.pa.us        4314                 :            188 :     appendPQExpBufferChar(tbloids, '}');
                               4315                 :                : 
                               4316                 :                :     /*
                               4317                 :                :      * Now, read all RLS policies belonging to the tables of interest, and
                               4318                 :                :      * create PolicyInfo objects for them.  (Note that we must filter the
                               4319                 :                :      * results server-side not locally, because we dare not apply pg_get_expr
                               4320                 :                :      * to tables we don't have lock on.)
                               4321                 :                :      */
 1518                          4322                 :            188 :     pg_log_info("reading row-level security policies");
                               4323                 :                : 
                               4324                 :            188 :     printfPQExpBuffer(query,
                               4325                 :                :                       "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
                               4326         [ +  - ]:            188 :     if (fout->remoteVersion >= 100000)
 1147 drowley@postgresql.o     4327                 :            188 :         appendPQExpBufferStr(query, "pol.polpermissive, ");
                               4328                 :                :     else
 1147 drowley@postgresql.o     4329                 :UBC           0 :         appendPQExpBufferStr(query, "'t' as polpermissive, ");
 1518 tgl@sss.pgh.pa.us        4330                 :CBC         188 :     appendPQExpBuffer(query,
                               4331                 :                :                       "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
                               4332                 :                :                       "   pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(rolname) from pg_catalog.pg_roles WHERE oid = ANY(pol.polroles)), ', ') END AS polroles, "
                               4333                 :                :                       "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
                               4334                 :                :                       "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
                               4335                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               4336                 :                :                       "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
                               4337                 :                :                       tbloids->data);
                               4338                 :                : 
                               4339                 :            188 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4340                 :                : 
                               4341                 :            188 :     ntups = PQntuples(res);
                               4342         [ +  + ]:            188 :     if (ntups > 0)
                               4343                 :                :     {
 4056 sfrost@snowman.net       4344                 :             43 :         i_oid = PQfnumber(res, "oid");
                               4345                 :             43 :         i_tableoid = PQfnumber(res, "tableoid");
 1518 tgl@sss.pgh.pa.us        4346                 :             43 :         i_polrelid = PQfnumber(res, "polrelid");
 3987 sfrost@snowman.net       4347                 :             43 :         i_polname = PQfnumber(res, "polname");
                               4348                 :             43 :         i_polcmd = PQfnumber(res, "polcmd");
 3248                          4349                 :             43 :         i_polpermissive = PQfnumber(res, "polpermissive");
 3987                          4350                 :             43 :         i_polroles = PQfnumber(res, "polroles");
                               4351                 :             43 :         i_polqual = PQfnumber(res, "polqual");
                               4352                 :             43 :         i_polwithcheck = PQfnumber(res, "polwithcheck");
                               4353                 :                : 
                               4354                 :             43 :         polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
                               4355                 :                : 
 4056                          4356         [ +  + ]:            316 :         for (j = 0; j < ntups; j++)
                               4357                 :                :         {
 1518 tgl@sss.pgh.pa.us        4358                 :            273 :             Oid         polrelid = atooid(PQgetvalue(res, j, i_polrelid));
                               4359                 :            273 :             TableInfo  *tbinfo = findTableByOid(polrelid);
                               4360                 :                : 
 1421                          4361                 :            273 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               4362                 :                : 
 3987 sfrost@snowman.net       4363                 :            273 :             polinfo[j].dobj.objType = DO_POLICY;
                               4364                 :            273 :             polinfo[j].dobj.catId.tableoid =
 4056                          4365                 :            273 :                 atooid(PQgetvalue(res, j, i_tableoid));
 3987                          4366                 :            273 :             polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               4367                 :            273 :             AssignDumpId(&polinfo[j].dobj);
                               4368                 :            273 :             polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4369                 :            273 :             polinfo[j].poltable = tbinfo;
                               4370                 :            273 :             polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
                               4371                 :            273 :             polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
                               4372                 :                : 
 3248                          4373                 :            273 :             polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
                               4374                 :            273 :             polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
                               4375                 :                : 
                               4376         [ +  + ]:            273 :             if (PQgetisnull(res, j, i_polroles))
                               4377                 :            121 :                 polinfo[j].polroles = NULL;
                               4378                 :                :             else
                               4379                 :            152 :                 polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
                               4380                 :                : 
 3987                          4381         [ +  + ]:            273 :             if (PQgetisnull(res, j, i_polqual))
                               4382                 :             38 :                 polinfo[j].polqual = NULL;
                               4383                 :                :             else
                               4384                 :            235 :                 polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
                               4385                 :                : 
                               4386         [ +  + ]:            273 :             if (PQgetisnull(res, j, i_polwithcheck))
                               4387                 :            144 :                 polinfo[j].polwithcheck = NULL;
                               4388                 :                :             else
                               4389                 :            129 :                 polinfo[j].polwithcheck
                               4390                 :            129 :                     = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
                               4391                 :                :         }
                               4392                 :                :     }
                               4393                 :                : 
 1518 tgl@sss.pgh.pa.us        4394                 :            188 :     PQclear(res);
                               4395                 :                : 
 4056 sfrost@snowman.net       4396                 :            188 :     destroyPQExpBuffer(query);
 1396 tgl@sss.pgh.pa.us        4397                 :            188 :     destroyPQExpBuffer(tbloids);
                               4398                 :                : }
                               4399                 :                : 
                               4400                 :                : /*
                               4401                 :                :  * dumpPolicy
                               4402                 :                :  *    dump the definition of the given policy
                               4403                 :                :  */
                               4404                 :                : static void
 1720 peter@eisentraut.org     4405                 :            326 : dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
                               4406                 :                : {
 3575 tgl@sss.pgh.pa.us        4407                 :            326 :     DumpOptions *dopt = fout->dopt;
 3987 sfrost@snowman.net       4408                 :            326 :     TableInfo  *tbinfo = polinfo->poltable;
                               4409                 :                :     PQExpBuffer query;
                               4410                 :                :     PQExpBuffer delqry;
                               4411                 :                :     PQExpBuffer polprefix;
                               4412                 :                :     char       *qtabname;
                               4413                 :                :     const char *cmd;
                               4414                 :                :     char       *tag;
                               4415                 :                : 
                               4416                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     4417         [ +  + ]:            326 :     if (!dopt->dumpSchema)
 4056 sfrost@snowman.net       4418                 :             49 :         return;
                               4419                 :                : 
                               4420                 :                :     /*
                               4421                 :                :      * If polname is NULL, then this record is just indicating that ROW LEVEL
                               4422                 :                :      * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
                               4423                 :                :      * ROW LEVEL SECURITY.
                               4424                 :                :      */
 3987                          4425         [ +  + ]:            277 :     if (polinfo->polname == NULL)
                               4426                 :                :     {
 4056                          4427                 :             46 :         query = createPQExpBuffer();
                               4428                 :                : 
                               4429                 :             46 :         appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
 2618 tgl@sss.pgh.pa.us        4430                 :             46 :                           fmtQualifiedDumpable(tbinfo));
                               4431                 :                : 
                               4432                 :                :         /*
                               4433                 :                :          * We must emit the ROW SECURITY object's dependency on its table
                               4434                 :                :          * explicitly, because it will not match anything in pg_depend (unlike
                               4435                 :                :          * the case for other PolicyInfo objects).
                               4436                 :                :          */
 1421                          4437         [ +  - ]:             46 :         if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3491 sfrost@snowman.net       4438                 :             46 :             ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.     4439                 :             46 :                          ARCHIVE_OPTS(.tag = polinfo->dobj.name,
                               4440                 :                :                                       .namespace = polinfo->dobj.namespace->dobj.name,
                               4441                 :                :                                       .owner = tbinfo->rolname,
                               4442                 :                :                                       .description = "ROW SECURITY",
                               4443                 :                :                                       .section = SECTION_POST_DATA,
                               4444                 :                :                                       .createStmt = query->data,
                               4445                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                               4446                 :                :                                       .nDeps = 1));
                               4447                 :                : 
 4056 sfrost@snowman.net       4448                 :             46 :         destroyPQExpBuffer(query);
                               4449                 :             46 :         return;
                               4450                 :                :     }
                               4451                 :                : 
 3248                          4452         [ +  + ]:            231 :     if (polinfo->polcmd == '*')
                               4453                 :             77 :         cmd = "";
                               4454         [ +  + ]:            154 :     else if (polinfo->polcmd == 'r')
                               4455                 :             41 :         cmd = " FOR SELECT";
                               4456         [ +  + ]:            113 :     else if (polinfo->polcmd == 'a')
                               4457                 :             31 :         cmd = " FOR INSERT";
                               4458         [ +  + ]:             82 :     else if (polinfo->polcmd == 'w')
                               4459                 :             41 :         cmd = " FOR UPDATE";
                               4460         [ +  - ]:             41 :     else if (polinfo->polcmd == 'd')
                               4461                 :             41 :         cmd = " FOR DELETE";
                               4462                 :                :     else
 1298 tgl@sss.pgh.pa.us        4463                 :UBC           0 :         pg_fatal("unexpected policy command type: %c",
                               4464                 :                :                  polinfo->polcmd);
                               4465                 :                : 
 4056 sfrost@snowman.net       4466                 :CBC         231 :     query = createPQExpBuffer();
                               4467                 :            231 :     delqry = createPQExpBuffer();
 2079 tgl@sss.pgh.pa.us        4468                 :            231 :     polprefix = createPQExpBuffer();
                               4469                 :                : 
                               4470                 :            231 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                               4471                 :                : 
 3929                          4472                 :            231 :     appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
                               4473                 :                : 
 2800                          4474                 :            231 :     appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
 3248 sfrost@snowman.net       4475         [ +  + ]:            231 :                       !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
                               4476                 :                : 
 3987                          4477         [ +  + ]:            231 :     if (polinfo->polroles != NULL)
                               4478                 :            124 :         appendPQExpBuffer(query, " TO %s", polinfo->polroles);
                               4479                 :                : 
                               4480         [ +  + ]:            231 :     if (polinfo->polqual != NULL)
 3745 mail@joeconway.com       4481                 :            200 :         appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
                               4482                 :                : 
 3987 sfrost@snowman.net       4483         [ +  + ]:            231 :     if (polinfo->polwithcheck != NULL)
 3745 mail@joeconway.com       4484                 :            108 :         appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
                               4485                 :                : 
 2307 drowley@postgresql.o     4486                 :            231 :     appendPQExpBufferStr(query, ";\n");
                               4487                 :                : 
 3929 tgl@sss.pgh.pa.us        4488                 :            231 :     appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
 2800                          4489                 :            231 :     appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
                               4490                 :                : 
 2079                          4491                 :            231 :     appendPQExpBuffer(polprefix, "POLICY %s ON",
                               4492                 :            231 :                       fmtId(polinfo->polname));
                               4493                 :                : 
 3532 peter_e@gmx.net          4494                 :            231 :     tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
                               4495                 :                : 
 1421 tgl@sss.pgh.pa.us        4496         [ +  - ]:            231 :     if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3491 sfrost@snowman.net       4497                 :            231 :         ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.     4498                 :            231 :                      ARCHIVE_OPTS(.tag = tag,
                               4499                 :                :                                   .namespace = polinfo->dobj.namespace->dobj.name,
                               4500                 :                :                                   .owner = tbinfo->rolname,
                               4501                 :                :                                   .description = "POLICY",
                               4502                 :                :                                   .section = SECTION_POST_DATA,
                               4503                 :                :                                   .createStmt = query->data,
                               4504                 :                :                                   .dropStmt = delqry->data));
                               4505                 :                : 
 2079 tgl@sss.pgh.pa.us        4506         [ +  + ]:            231 :     if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                               4507                 :             31 :         dumpComment(fout, polprefix->data, qtabname,
                               4508                 :             31 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                               4509                 :             31 :                     polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
                               4510                 :                : 
 3532 peter_e@gmx.net          4511                 :            231 :     free(tag);
 4056 sfrost@snowman.net       4512                 :            231 :     destroyPQExpBuffer(query);
                               4513                 :            231 :     destroyPQExpBuffer(delqry);
 2079 tgl@sss.pgh.pa.us        4514                 :            231 :     destroyPQExpBuffer(polprefix);
                               4515                 :            231 :     free(qtabname);
                               4516                 :                : }
                               4517                 :                : 
                               4518                 :                : /*
                               4519                 :                :  * getPublications
                               4520                 :                :  *    get information about publications
                               4521                 :                :  */
                               4522                 :                : void
  482 nathan@postgresql.or     4523                 :            189 : getPublications(Archive *fout)
                               4524                 :                : {
 3090 peter_e@gmx.net          4525                 :            189 :     DumpOptions *dopt = fout->dopt;
                               4526                 :                :     PQExpBuffer query;
                               4527                 :                :     PGresult   *res;
                               4528                 :                :     PublicationInfo *pubinfo;
                               4529                 :                :     int         i_tableoid;
                               4530                 :                :     int         i_oid;
                               4531                 :                :     int         i_pubname;
                               4532                 :                :     int         i_pubowner;
                               4533                 :                :     int         i_puballtables;
                               4534                 :                :     int         i_puballsequences;
                               4535                 :                :     int         i_pubinsert;
                               4536                 :                :     int         i_pubupdate;
                               4537                 :                :     int         i_pubdelete;
                               4538                 :                :     int         i_pubtruncate;
                               4539                 :                :     int         i_pubviaroot;
                               4540                 :                :     int         i_pubgencols;
                               4541                 :                :     int         i,
                               4542                 :                :                 ntups;
                               4543                 :                : 
                               4544   [ +  -  -  + ]:            189 :     if (dopt->no_publications || fout->remoteVersion < 100000)
  482 nathan@postgresql.or     4545                 :UBC           0 :         return;
                               4546                 :                : 
 3203 peter_e@gmx.net          4547                 :CBC         189 :     query = createPQExpBuffer();
                               4548                 :                : 
                               4549                 :                :     /* Get the publications. */
  354 akapila@postgresql.o     4550                 :            189 :     appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, "
                               4551                 :                :                          "p.pubowner, p.puballtables, p.pubinsert, "
                               4552                 :                :                          "p.pubupdate, p.pubdelete, ");
                               4553                 :                : 
                               4554         [ +  - ]:            189 :     if (fout->remoteVersion >= 110000)
                               4555                 :            189 :         appendPQExpBufferStr(query, "p.pubtruncate, ");
                               4556                 :                :     else
  354 akapila@postgresql.o     4557                 :UBC           0 :         appendPQExpBufferStr(query, "false AS pubtruncate, ");
                               4558                 :                : 
 1299 tomas.vondra@postgre     4559         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 130000)
  354 akapila@postgresql.o     4560                 :            189 :         appendPQExpBufferStr(query, "p.pubviaroot, ");
                               4561                 :                :     else
  354 akapila@postgresql.o     4562                 :UBC           0 :         appendPQExpBufferStr(query, "false AS pubviaroot, ");
                               4563                 :                : 
  354 akapila@postgresql.o     4564         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 180000)
   18 akapila@postgresql.o     4565                 :GNC         189 :         appendPQExpBufferStr(query, "p.pubgencols, ");
                               4566                 :                :     else
   18 akapila@postgresql.o     4567                 :UNC           0 :         appendPQExpBuffer(query, "'%c' AS pubgencols, ", PUBLISH_GENCOLS_NONE);
                               4568                 :                : 
   18 akapila@postgresql.o     4569         [ +  - ]:GNC         189 :     if (fout->remoteVersion >= 190000)
                               4570                 :            189 :         appendPQExpBufferStr(query, "p.puballsequences ");
                               4571                 :                :     else
   18 akapila@postgresql.o     4572                 :UNC           0 :         appendPQExpBufferStr(query, "false AS puballsequences ");
                               4573                 :                : 
  354 akapila@postgresql.o     4574                 :CBC         189 :     appendPQExpBufferStr(query, "FROM pg_publication p");
                               4575                 :                : 
 3203 peter_e@gmx.net          4576                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4577                 :                : 
                               4578                 :            189 :     ntups = PQntuples(res);
                               4579                 :                : 
  390 dgustafsson@postgres     4580         [ +  + ]:            189 :     if (ntups == 0)
                               4581                 :            136 :         goto cleanup;
                               4582                 :                : 
 3203 peter_e@gmx.net          4583                 :             53 :     i_tableoid = PQfnumber(res, "tableoid");
                               4584                 :             53 :     i_oid = PQfnumber(res, "oid");
                               4585                 :             53 :     i_pubname = PQfnumber(res, "pubname");
 1396 tgl@sss.pgh.pa.us        4586                 :             53 :     i_pubowner = PQfnumber(res, "pubowner");
 3203 peter_e@gmx.net          4587                 :             53 :     i_puballtables = PQfnumber(res, "puballtables");
   18 akapila@postgresql.o     4588                 :GNC          53 :     i_puballsequences = PQfnumber(res, "puballsequences");
 3203 peter_e@gmx.net          4589                 :CBC          53 :     i_pubinsert = PQfnumber(res, "pubinsert");
                               4590                 :             53 :     i_pubupdate = PQfnumber(res, "pubupdate");
                               4591                 :             53 :     i_pubdelete = PQfnumber(res, "pubdelete");
 2760                          4592                 :             53 :     i_pubtruncate = PQfnumber(res, "pubtruncate");
 2028 peter@eisentraut.org     4593                 :             53 :     i_pubviaroot = PQfnumber(res, "pubviaroot");
  272 akapila@postgresql.o     4594                 :             53 :     i_pubgencols = PQfnumber(res, "pubgencols");
                               4595                 :                : 
 3203 peter_e@gmx.net          4596                 :             53 :     pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
                               4597                 :                : 
                               4598         [ +  + ]:            404 :     for (i = 0; i < ntups; i++)
                               4599                 :                :     {
                               4600                 :            351 :         pubinfo[i].dobj.objType = DO_PUBLICATION;
                               4601                 :            351 :         pubinfo[i].dobj.catId.tableoid =
                               4602                 :            351 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4603                 :            351 :         pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4604                 :            351 :         AssignDumpId(&pubinfo[i].dobj);
                               4605                 :            351 :         pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
 1396 tgl@sss.pgh.pa.us        4606                 :            351 :         pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
 3203 peter_e@gmx.net          4607                 :            351 :         pubinfo[i].puballtables =
                               4608                 :            351 :             (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
   18 akapila@postgresql.o     4609                 :GNC         351 :         pubinfo[i].puballsequences =
                               4610                 :            351 :             (strcmp(PQgetvalue(res, i, i_puballsequences), "t") == 0);
 3203 peter_e@gmx.net          4611                 :CBC         351 :         pubinfo[i].pubinsert =
                               4612                 :            351 :             (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
                               4613                 :            351 :         pubinfo[i].pubupdate =
                               4614                 :            351 :             (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
                               4615                 :            351 :         pubinfo[i].pubdelete =
                               4616                 :            351 :             (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
 2760                          4617                 :            351 :         pubinfo[i].pubtruncate =
                               4618                 :            351 :             (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
 2028 peter@eisentraut.org     4619                 :            351 :         pubinfo[i].pubviaroot =
                               4620                 :            351 :             (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
  277 akapila@postgresql.o     4621                 :            351 :         pubinfo[i].pubgencols_type =
  272                          4622                 :            351 :             *(PQgetvalue(res, i, i_pubgencols));
                               4623                 :                : 
                               4624                 :                :         /* Decide whether we want to dump it */
 3142 peter_e@gmx.net          4625                 :            351 :         selectDumpableObject(&(pubinfo[i].dobj), fout);
                               4626                 :                :     }
                               4627                 :                : 
  390 dgustafsson@postgres     4628                 :             53 : cleanup:
 3203 peter_e@gmx.net          4629                 :            189 :     PQclear(res);
                               4630                 :                : 
                               4631                 :            189 :     destroyPQExpBuffer(query);
                               4632                 :                : }
                               4633                 :                : 
                               4634                 :                : /*
                               4635                 :                :  * dumpPublication
                               4636                 :                :  *    dump the definition of the given publication
                               4637                 :                :  */
                               4638                 :                : static void
 1720 peter@eisentraut.org     4639                 :            285 : dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
                               4640                 :                : {
 1397 tgl@sss.pgh.pa.us        4641                 :            285 :     DumpOptions *dopt = fout->dopt;
                               4642                 :                :     PQExpBuffer delq;
                               4643                 :                :     PQExpBuffer query;
                               4644                 :                :     char       *qpubname;
 3090 peter_e@gmx.net          4645                 :            285 :     bool        first = true;
                               4646                 :                : 
                               4647                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     4648         [ +  + ]:            285 :     if (!dopt->dumpSchema)
 1397 tgl@sss.pgh.pa.us        4649                 :             42 :         return;
                               4650                 :                : 
 3203 peter_e@gmx.net          4651                 :            243 :     delq = createPQExpBuffer();
                               4652                 :            243 :     query = createPQExpBuffer();
                               4653                 :                : 
 2800 tgl@sss.pgh.pa.us        4654                 :            243 :     qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
                               4655                 :                : 
 3203 peter_e@gmx.net          4656                 :            243 :     appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
                               4657                 :                :                       qpubname);
                               4658                 :                : 
                               4659                 :            243 :     appendPQExpBuffer(query, "CREATE PUBLICATION %s",
                               4660                 :                :                       qpubname);
                               4661                 :                : 
   18 akapila@postgresql.o     4662   [ +  +  +  + ]:GNC         243 :     if (pubinfo->puballtables && pubinfo->puballsequences)
                               4663                 :             31 :         appendPQExpBufferStr(query, " FOR ALL TABLES, ALL SEQUENCES");
                               4664         [ +  + ]:            212 :     else if (pubinfo->puballtables)
 3203 peter_e@gmx.net          4665                 :CBC          32 :         appendPQExpBufferStr(query, " FOR ALL TABLES");
   18 akapila@postgresql.o     4666         [ +  + ]:GNC         180 :     else if (pubinfo->puballsequences)
                               4667                 :             31 :         appendPQExpBufferStr(query, " FOR ALL SEQUENCES");
                               4668                 :                : 
 3090 peter_e@gmx.net          4669                 :CBC         243 :     appendPQExpBufferStr(query, " WITH (publish = '");
 3203                          4670         [ +  + ]:            243 :     if (pubinfo->pubinsert)
                               4671                 :                :     {
 3090                          4672                 :            181 :         appendPQExpBufferStr(query, "insert");
                               4673                 :            181 :         first = false;
                               4674                 :                :     }
                               4675                 :                : 
 3203                          4676         [ +  + ]:            243 :     if (pubinfo->pubupdate)
                               4677                 :                :     {
 3087 tgl@sss.pgh.pa.us        4678         [ +  - ]:            181 :         if (!first)
                               4679                 :            181 :             appendPQExpBufferStr(query, ", ");
                               4680                 :                : 
 3090 peter_e@gmx.net          4681                 :            181 :         appendPQExpBufferStr(query, "update");
                               4682                 :            181 :         first = false;
                               4683                 :                :     }
                               4684                 :                : 
 3203                          4685         [ +  + ]:            243 :     if (pubinfo->pubdelete)
                               4686                 :                :     {
 3087 tgl@sss.pgh.pa.us        4687         [ +  - ]:            181 :         if (!first)
                               4688                 :            181 :             appendPQExpBufferStr(query, ", ");
                               4689                 :                : 
 3090 peter_e@gmx.net          4690                 :            181 :         appendPQExpBufferStr(query, "delete");
                               4691                 :            181 :         first = false;
                               4692                 :                :     }
                               4693                 :                : 
 2760                          4694         [ +  + ]:            243 :     if (pubinfo->pubtruncate)
                               4695                 :                :     {
                               4696         [ +  - ]:            181 :         if (!first)
                               4697                 :            181 :             appendPQExpBufferStr(query, ", ");
                               4698                 :                : 
                               4699                 :            181 :         appendPQExpBufferStr(query, "truncate");
                               4700                 :            181 :         first = false;
                               4701                 :                :     }
                               4702                 :                : 
 1147 drowley@postgresql.o     4703                 :            243 :     appendPQExpBufferChar(query, '\'');
                               4704                 :                : 
 2028 peter@eisentraut.org     4705         [ +  + ]:            243 :     if (pubinfo->pubviaroot)
                               4706                 :              5 :         appendPQExpBufferStr(query, ", publish_via_partition_root = true");
                               4707                 :                : 
  277 akapila@postgresql.o     4708         [ +  + ]:            243 :     if (pubinfo->pubgencols_type == PUBLISH_GENCOLS_STORED)
                               4709                 :             31 :         appendPQExpBufferStr(query, ", publish_generated_columns = stored");
                               4710                 :                : 
 2028 peter@eisentraut.org     4711                 :            243 :     appendPQExpBufferStr(query, ");\n");
                               4712                 :                : 
 1421 tgl@sss.pgh.pa.us        4713         [ +  - ]:            243 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4714                 :            243 :         ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
                               4715                 :            243 :                      ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
                               4716                 :                :                                   .owner = pubinfo->rolname,
                               4717                 :                :                                   .description = "PUBLICATION",
                               4718                 :                :                                   .section = SECTION_POST_DATA,
                               4719                 :                :                                   .createStmt = query->data,
                               4720                 :                :                                   .dropStmt = delq->data));
                               4721                 :                : 
 3119 peter_e@gmx.net          4722         [ +  + ]:            243 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us        4723                 :             31 :         dumpComment(fout, "PUBLICATION", qpubname,
 3119 peter_e@gmx.net          4724                 :             31 :                     NULL, pubinfo->rolname,
                               4725                 :             31 :                     pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4726                 :                : 
                               4727         [ -  + ]:            243 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us        4728                 :UBC           0 :         dumpSecLabel(fout, "PUBLICATION", qpubname,
 3119 peter_e@gmx.net          4729                 :              0 :                      NULL, pubinfo->rolname,
                               4730                 :              0 :                      pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4731                 :                : 
 3203 peter_e@gmx.net          4732                 :CBC         243 :     destroyPQExpBuffer(delq);
                               4733                 :            243 :     destroyPQExpBuffer(query);
 2800 tgl@sss.pgh.pa.us        4734                 :            243 :     free(qpubname);
                               4735                 :                : }
                               4736                 :                : 
                               4737                 :                : /*
                               4738                 :                :  * getPublicationNamespaces
                               4739                 :                :  *    get information about publication membership for dumpable schemas.
                               4740                 :                :  */
                               4741                 :                : void
 1461 akapila@postgresql.o     4742                 :            189 : getPublicationNamespaces(Archive *fout)
                               4743                 :                : {
                               4744                 :                :     PQExpBuffer query;
                               4745                 :                :     PGresult   *res;
                               4746                 :                :     PublicationSchemaInfo *pubsinfo;
                               4747                 :            189 :     DumpOptions *dopt = fout->dopt;
                               4748                 :                :     int         i_tableoid;
                               4749                 :                :     int         i_oid;
                               4750                 :                :     int         i_pnpubid;
                               4751                 :                :     int         i_pnnspid;
                               4752                 :                :     int         i,
                               4753                 :                :                 j,
                               4754                 :                :                 ntups;
                               4755                 :                : 
                               4756   [ +  -  -  + ]:            189 :     if (dopt->no_publications || fout->remoteVersion < 150000)
 1461 akapila@postgresql.o     4757                 :UBC           0 :         return;
                               4758                 :                : 
 1461 akapila@postgresql.o     4759                 :CBC         189 :     query = createPQExpBuffer();
                               4760                 :                : 
                               4761                 :                :     /* Collect all publication membership info. */
                               4762                 :            189 :     appendPQExpBufferStr(query,
                               4763                 :                :                          "SELECT tableoid, oid, pnpubid, pnnspid "
                               4764                 :                :                          "FROM pg_catalog.pg_publication_namespace");
                               4765                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4766                 :                : 
                               4767                 :            189 :     ntups = PQntuples(res);
                               4768                 :                : 
                               4769                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               4770                 :            189 :     i_oid = PQfnumber(res, "oid");
                               4771                 :            189 :     i_pnpubid = PQfnumber(res, "pnpubid");
                               4772                 :            189 :     i_pnnspid = PQfnumber(res, "pnnspid");
                               4773                 :                : 
                               4774                 :                :     /* this allocation may be more than we need */
                               4775                 :            189 :     pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
                               4776                 :            189 :     j = 0;
                               4777                 :                : 
                               4778         [ +  + ]:            314 :     for (i = 0; i < ntups; i++)
                               4779                 :                :     {
                               4780                 :            125 :         Oid         pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
                               4781                 :            125 :         Oid         pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
                               4782                 :                :         PublicationInfo *pubinfo;
                               4783                 :                :         NamespaceInfo *nspinfo;
                               4784                 :                : 
                               4785                 :                :         /*
                               4786                 :                :          * Ignore any entries for which we aren't interested in either the
                               4787                 :                :          * publication or the rel.
                               4788                 :                :          */
                               4789                 :            125 :         pubinfo = findPublicationByOid(pnpubid);
                               4790         [ -  + ]:            125 :         if (pubinfo == NULL)
 1461 akapila@postgresql.o     4791                 :UBC           0 :             continue;
 1461 akapila@postgresql.o     4792                 :CBC         125 :         nspinfo = findNamespaceByOid(pnnspid);
                               4793         [ -  + ]:            125 :         if (nspinfo == NULL)
 1461 akapila@postgresql.o     4794                 :UBC           0 :             continue;
                               4795                 :                : 
                               4796                 :                :         /* OK, make a DumpableObject for this relationship */
 1448 akapila@postgresql.o     4797                 :CBC         125 :         pubsinfo[j].dobj.objType = DO_PUBLICATION_TABLE_IN_SCHEMA;
 1461                          4798                 :            125 :         pubsinfo[j].dobj.catId.tableoid =
                               4799                 :            125 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4800                 :            125 :         pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4801                 :            125 :         AssignDumpId(&pubsinfo[j].dobj);
                               4802                 :            125 :         pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
                               4803                 :            125 :         pubsinfo[j].dobj.name = nspinfo->dobj.name;
                               4804                 :            125 :         pubsinfo[j].publication = pubinfo;
                               4805                 :            125 :         pubsinfo[j].pubschema = nspinfo;
                               4806                 :                : 
                               4807                 :                :         /* Decide whether we want to dump it */
                               4808                 :            125 :         selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
                               4809                 :                : 
                               4810                 :            125 :         j++;
                               4811                 :                :     }
                               4812                 :                : 
                               4813                 :            189 :     PQclear(res);
                               4814                 :            189 :     destroyPQExpBuffer(query);
                               4815                 :                : }
                               4816                 :                : 
                               4817                 :                : /*
                               4818                 :                :  * getPublicationTables
                               4819                 :                :  *    get information about publication membership for dumpable tables.
                               4820                 :                :  */
                               4821                 :                : void
 3203 peter_e@gmx.net          4822                 :            189 : getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
                               4823                 :                : {
                               4824                 :                :     PQExpBuffer query;
                               4825                 :                :     PGresult   *res;
                               4826                 :                :     PublicationRelInfo *pubrinfo;
 2589 michael@paquier.xyz      4827                 :            189 :     DumpOptions *dopt = fout->dopt;
                               4828                 :                :     int         i_tableoid;
                               4829                 :                :     int         i_oid;
                               4830                 :                :     int         i_prpubid;
                               4831                 :                :     int         i_prrelid;
                               4832                 :                :     int         i_prrelqual;
                               4833                 :                :     int         i_prattrs;
                               4834                 :                :     int         i,
                               4835                 :                :                 j,
                               4836                 :                :                 ntups;
                               4837                 :                : 
                               4838   [ +  -  -  + ]:            189 :     if (dopt->no_publications || fout->remoteVersion < 100000)
 3203 peter_e@gmx.net          4839                 :UBC           0 :         return;
                               4840                 :                : 
 3203 peter_e@gmx.net          4841                 :CBC         189 :     query = createPQExpBuffer();
                               4842                 :                : 
                               4843                 :                :     /* Collect all publication membership info. */
 1343 akapila@postgresql.o     4844         [ +  - ]:            189 :     if (fout->remoteVersion >= 150000)
                               4845                 :            189 :         appendPQExpBufferStr(query,
                               4846                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4847                 :                :                              "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
                               4848                 :                :                              "(CASE\n"
                               4849                 :                :                              "  WHEN pr.prattrs IS NOT NULL THEN\n"
                               4850                 :                :                              "    (SELECT array_agg(attname)\n"
                               4851                 :                :                              "       FROM\n"
                               4852                 :                :                              "         pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
                               4853                 :                :                              "         pg_catalog.pg_attribute\n"
                               4854                 :                :                              "      WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
                               4855                 :                :                              "  ELSE NULL END) prattrs "
                               4856                 :                :                              "FROM pg_catalog.pg_publication_rel pr");
                               4857                 :                :     else
 1343 akapila@postgresql.o     4858                 :UBC           0 :         appendPQExpBufferStr(query,
                               4859                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4860                 :                :                              "NULL AS prrelqual, NULL AS prattrs "
                               4861                 :                :                              "FROM pg_catalog.pg_publication_rel");
 1747 tgl@sss.pgh.pa.us        4862                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4863                 :                : 
                               4864                 :            189 :     ntups = PQntuples(res);
                               4865                 :                : 
                               4866                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               4867                 :            189 :     i_oid = PQfnumber(res, "oid");
                               4868                 :            189 :     i_prpubid = PQfnumber(res, "prpubid");
                               4869                 :            189 :     i_prrelid = PQfnumber(res, "prrelid");
 1343 akapila@postgresql.o     4870                 :            189 :     i_prrelqual = PQfnumber(res, "prrelqual");
 1311 tomas.vondra@postgre     4871                 :            189 :     i_prattrs = PQfnumber(res, "prattrs");
                               4872                 :                : 
                               4873                 :                :     /* this allocation may be more than we need */
 1747 tgl@sss.pgh.pa.us        4874                 :            189 :     pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
                               4875                 :            189 :     j = 0;
                               4876                 :                : 
                               4877         [ +  + ]:            539 :     for (i = 0; i < ntups; i++)
                               4878                 :                :     {
                               4879                 :            350 :         Oid         prpubid = atooid(PQgetvalue(res, i, i_prpubid));
                               4880                 :            350 :         Oid         prrelid = atooid(PQgetvalue(res, i, i_prrelid));
                               4881                 :                :         PublicationInfo *pubinfo;
                               4882                 :                :         TableInfo  *tbinfo;
                               4883                 :                : 
                               4884                 :                :         /*
                               4885                 :                :          * Ignore any entries for which we aren't interested in either the
                               4886                 :                :          * publication or the rel.
                               4887                 :                :          */
                               4888                 :            350 :         pubinfo = findPublicationByOid(prpubid);
                               4889         [ -  + ]:            350 :         if (pubinfo == NULL)
 1747 tgl@sss.pgh.pa.us        4890                 :UBC           0 :             continue;
 1747 tgl@sss.pgh.pa.us        4891                 :CBC         350 :         tbinfo = findTableByOid(prrelid);
                               4892         [ -  + ]:            350 :         if (tbinfo == NULL)
 3203 peter_e@gmx.net          4893                 :UBC           0 :             continue;
                               4894                 :                : 
                               4895                 :                :         /* OK, make a DumpableObject for this relationship */
 1747 tgl@sss.pgh.pa.us        4896                 :CBC         350 :         pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
                               4897                 :            350 :         pubrinfo[j].dobj.catId.tableoid =
                               4898                 :            350 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4899                 :            350 :         pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4900                 :            350 :         AssignDumpId(&pubrinfo[j].dobj);
                               4901                 :            350 :         pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4902                 :            350 :         pubrinfo[j].dobj.name = tbinfo->dobj.name;
                               4903                 :            350 :         pubrinfo[j].publication = pubinfo;
                               4904                 :            350 :         pubrinfo[j].pubtable = tbinfo;
 1343 akapila@postgresql.o     4905         [ +  + ]:            350 :         if (PQgetisnull(res, i, i_prrelqual))
                               4906                 :            194 :             pubrinfo[j].pubrelqual = NULL;
                               4907                 :                :         else
                               4908                 :            156 :             pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
                               4909                 :                : 
 1311 tomas.vondra@postgre     4910         [ +  + ]:            350 :         if (!PQgetisnull(res, i, i_prattrs))
                               4911                 :                :         {
                               4912                 :                :             char      **attnames;
                               4913                 :                :             int         nattnames;
                               4914                 :                :             PQExpBuffer attribs;
                               4915                 :                : 
                               4916         [ -  + ]:            111 :             if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
                               4917                 :                :                               &attnames, &nattnames))
 1298 tgl@sss.pgh.pa.us        4918                 :UBC           0 :                 pg_fatal("could not parse %s array", "prattrs");
 1311 tomas.vondra@postgre     4919                 :CBC         111 :             attribs = createPQExpBuffer();
                               4920         [ +  + ]:            319 :             for (int k = 0; k < nattnames; k++)
                               4921                 :                :             {
                               4922         [ +  + ]:            208 :                 if (k > 0)
                               4923                 :             97 :                     appendPQExpBufferStr(attribs, ", ");
                               4924                 :                : 
                               4925                 :            208 :                 appendPQExpBufferStr(attribs, fmtId(attnames[k]));
                               4926                 :                :             }
                               4927                 :            111 :             pubrinfo[j].pubrattrs = attribs->data;
  257 tgl@sss.pgh.pa.us        4928                 :            111 :             free(attribs);      /* but not attribs->data */
                               4929                 :            111 :             free(attnames);
                               4930                 :                :         }
                               4931                 :                :         else
 1311 tomas.vondra@postgre     4932                 :            239 :             pubrinfo[j].pubrattrs = NULL;
                               4933                 :                : 
                               4934                 :                :         /* Decide whether we want to dump it */
 1461 akapila@postgresql.o     4935                 :            350 :         selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
                               4936                 :                : 
 1747 tgl@sss.pgh.pa.us        4937                 :            350 :         j++;
                               4938                 :                :     }
                               4939                 :                : 
                               4940                 :            189 :     PQclear(res);
 3203 peter_e@gmx.net          4941                 :            189 :     destroyPQExpBuffer(query);
                               4942                 :                : }
                               4943                 :                : 
                               4944                 :                : /*
                               4945                 :                :  * dumpPublicationNamespace
                               4946                 :                :  *    dump the definition of the given publication schema mapping.
                               4947                 :                :  */
                               4948                 :                : static void
 1461 akapila@postgresql.o     4949                 :             99 : dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
                               4950                 :                : {
 1397 tgl@sss.pgh.pa.us        4951                 :             99 :     DumpOptions *dopt = fout->dopt;
 1461 akapila@postgresql.o     4952                 :             99 :     NamespaceInfo *schemainfo = pubsinfo->pubschema;
                               4953                 :             99 :     PublicationInfo *pubinfo = pubsinfo->publication;
                               4954                 :                :     PQExpBuffer query;
                               4955                 :                :     char       *tag;
                               4956                 :                : 
                               4957                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     4958         [ +  + ]:             99 :     if (!dopt->dumpSchema)
 1461 akapila@postgresql.o     4959                 :             12 :         return;
                               4960                 :                : 
                               4961                 :             87 :     tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
                               4962                 :                : 
                               4963                 :             87 :     query = createPQExpBuffer();
                               4964                 :                : 
                               4965                 :             87 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
 1131 alvherre@alvh.no-ip.     4966                 :             87 :     appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
                               4967                 :                : 
                               4968                 :                :     /*
                               4969                 :                :      * There is no point in creating drop query as the drop is done by schema
                               4970                 :                :      * drop.
                               4971                 :                :      */
 1397 tgl@sss.pgh.pa.us        4972         [ +  - ]:             87 :     if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4973                 :             87 :         ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
                               4974                 :             87 :                      ARCHIVE_OPTS(.tag = tag,
                               4975                 :                :                                   .namespace = schemainfo->dobj.name,
                               4976                 :                :                                   .owner = pubinfo->rolname,
                               4977                 :                :                                   .description = "PUBLICATION TABLES IN SCHEMA",
                               4978                 :                :                                   .section = SECTION_POST_DATA,
                               4979                 :                :                                   .createStmt = query->data));
                               4980                 :                : 
                               4981                 :                :     /* These objects can't currently have comments or seclabels */
                               4982                 :                : 
 1461 akapila@postgresql.o     4983                 :             87 :     free(tag);
                               4984                 :             87 :     destroyPQExpBuffer(query);
                               4985                 :                : }
                               4986                 :                : 
                               4987                 :                : /*
                               4988                 :                :  * dumpPublicationTable
                               4989                 :                :  *    dump the definition of the given publication table mapping
                               4990                 :                :  */
                               4991                 :                : static void
 1720 peter@eisentraut.org     4992                 :            284 : dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
                               4993                 :                : {
 1397 tgl@sss.pgh.pa.us        4994                 :            284 :     DumpOptions *dopt = fout->dopt;
 1747                          4995                 :            284 :     PublicationInfo *pubinfo = pubrinfo->publication;
 3203 peter_e@gmx.net          4996                 :            284 :     TableInfo  *tbinfo = pubrinfo->pubtable;
                               4997                 :                :     PQExpBuffer query;
                               4998                 :                :     char       *tag;
                               4999                 :                : 
                               5000                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     5001         [ +  + ]:            284 :     if (!dopt->dumpSchema)
 1397 tgl@sss.pgh.pa.us        5002                 :             42 :         return;
                               5003                 :                : 
 1747                          5004                 :            242 :     tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
                               5005                 :                : 
 3203 peter_e@gmx.net          5006                 :            242 :     query = createPQExpBuffer();
                               5007                 :                : 
 1299 tomas.vondra@postgre     5008                 :            242 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
                               5009                 :            242 :                       fmtId(pubinfo->dobj.name));
 1343 akapila@postgresql.o     5010                 :            242 :     appendPQExpBuffer(query, " %s",
 2800 tgl@sss.pgh.pa.us        5011                 :            242 :                       fmtQualifiedDumpable(tbinfo));
                               5012                 :                : 
 1311 tomas.vondra@postgre     5013         [ +  + ]:            242 :     if (pubrinfo->pubrattrs)
                               5014                 :             77 :         appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
                               5015                 :                : 
 1343 akapila@postgresql.o     5016         [ +  + ]:            242 :     if (pubrinfo->pubrelqual)
                               5017                 :                :     {
                               5018                 :                :         /*
                               5019                 :                :          * It's necessary to add parentheses around the expression because
                               5020                 :                :          * pg_get_expr won't supply the parentheses for things like WHERE
                               5021                 :                :          * TRUE.
                               5022                 :                :          */
                               5023                 :            108 :         appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
                               5024                 :                :     }
                               5025                 :            242 :     appendPQExpBufferStr(query, ";\n");
                               5026                 :                : 
                               5027                 :                :     /*
                               5028                 :                :      * There is no point in creating a drop query as the drop is done by table
                               5029                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               5030                 :                :      * Although this object doesn't really have ownership as such, set the
                               5031                 :                :      * owner field anyway to ensure that the command is run by the correct
                               5032                 :                :      * role at restore time.
                               5033                 :                :      */
 1421 tgl@sss.pgh.pa.us        5034         [ +  - ]:            242 :     if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5035                 :            242 :         ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
                               5036                 :            242 :                      ARCHIVE_OPTS(.tag = tag,
                               5037                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               5038                 :                :                                   .owner = pubinfo->rolname,
                               5039                 :                :                                   .description = "PUBLICATION TABLE",
                               5040                 :                :                                   .section = SECTION_POST_DATA,
                               5041                 :                :                                   .createStmt = query->data));
                               5042                 :                : 
                               5043                 :                :     /* These objects can't currently have comments or seclabels */
                               5044                 :                : 
 3203 peter_e@gmx.net          5045                 :            242 :     free(tag);
                               5046                 :            242 :     destroyPQExpBuffer(query);
                               5047                 :                : }
                               5048                 :                : 
                               5049                 :                : /*
                               5050                 :                :  * Is the currently connected user a superuser?
                               5051                 :                :  */
                               5052                 :                : static bool
 3121                          5053                 :            188 : is_superuser(Archive *fout)
                               5054                 :                : {
                               5055                 :            188 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                               5056                 :                :     const char *val;
                               5057                 :                : 
                               5058                 :            188 :     val = PQparameterStatus(AH->connection, "is_superuser");
                               5059                 :                : 
                               5060   [ +  -  +  + ]:            188 :     if (val && strcmp(val, "on") == 0)
                               5061                 :            185 :         return true;
                               5062                 :                : 
                               5063                 :              3 :     return false;
                               5064                 :                : }
                               5065                 :                : 
                               5066                 :                : /*
                               5067                 :                :  * Set the given value to restrict_nonsystem_relation_kind value. Since
                               5068                 :                :  * restrict_nonsystem_relation_kind is introduced in minor version releases,
                               5069                 :                :  * the setting query is effective only where available.
                               5070                 :                :  */
                               5071                 :                : static void
  448 msawada@postgresql.o     5072                 :            225 : set_restrict_relation_kind(Archive *AH, const char *value)
                               5073                 :                : {
                               5074                 :            225 :     PQExpBuffer query = createPQExpBuffer();
                               5075                 :                :     PGresult   *res;
                               5076                 :                : 
                               5077                 :            225 :     appendPQExpBuffer(query,
                               5078                 :                :                       "SELECT set_config(name, '%s', false) "
                               5079                 :                :                       "FROM pg_settings "
                               5080                 :                :                       "WHERE name = 'restrict_nonsystem_relation_kind'",
                               5081                 :                :                       value);
                               5082                 :            225 :     res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
                               5083                 :                : 
                               5084                 :            225 :     PQclear(res);
                               5085                 :            225 :     destroyPQExpBuffer(query);
                               5086                 :            225 : }
                               5087                 :                : 
                               5088                 :                : /*
                               5089                 :                :  * getSubscriptions
                               5090                 :                :  *    get information about subscriptions
                               5091                 :                :  */
                               5092                 :                : void
 3203 peter_e@gmx.net          5093                 :            189 : getSubscriptions(Archive *fout)
                               5094                 :                : {
 3093                          5095                 :            189 :     DumpOptions *dopt = fout->dopt;
                               5096                 :                :     PQExpBuffer query;
                               5097                 :                :     PGresult   *res;
                               5098                 :                :     SubscriptionInfo *subinfo;
                               5099                 :                :     int         i_tableoid;
                               5100                 :                :     int         i_oid;
                               5101                 :                :     int         i_subname;
                               5102                 :                :     int         i_subowner;
                               5103                 :                :     int         i_subbinary;
                               5104                 :                :     int         i_substream;
                               5105                 :                :     int         i_subtwophasestate;
                               5106                 :                :     int         i_subdisableonerr;
                               5107                 :                :     int         i_subpasswordrequired;
                               5108                 :                :     int         i_subrunasowner;
                               5109                 :                :     int         i_subconninfo;
                               5110                 :                :     int         i_subslotname;
                               5111                 :                :     int         i_subsynccommit;
                               5112                 :                :     int         i_subpublications;
                               5113                 :                :     int         i_suborigin;
                               5114                 :                :     int         i_suboriginremotelsn;
                               5115                 :                :     int         i_subenabled;
                               5116                 :                :     int         i_subfailover;
                               5117                 :                :     int         i_subretaindeadtuples;
                               5118                 :                :     int         i_submaxretention;
                               5119                 :                :     int         i,
                               5120                 :                :                 ntups;
                               5121                 :                : 
                               5122   [ +  +  -  + ]:            189 :     if (dopt->no_subscriptions || fout->remoteVersion < 100000)
 3121                          5123                 :              1 :         return;
                               5124                 :                : 
                               5125         [ +  + ]:            188 :     if (!is_superuser(fout))
                               5126                 :                :     {
                               5127                 :                :         int         n;
                               5128                 :                : 
                               5129                 :              3 :         res = ExecuteSqlQuery(fout,
                               5130                 :                :                               "SELECT count(*) FROM pg_subscription "
                               5131                 :                :                               "WHERE subdbid = (SELECT oid FROM pg_database"
                               5132                 :                :                               "                 WHERE datname = current_database())",
                               5133                 :                :                               PGRES_TUPLES_OK);
                               5134                 :              3 :         n = atoi(PQgetvalue(res, 0, 0));
                               5135         [ +  + ]:              3 :         if (n > 0)
 2401 peter@eisentraut.org     5136                 :              2 :             pg_log_warning("subscriptions not dumped because current user is not a superuser");
 3121 peter_e@gmx.net          5137                 :              3 :         PQclear(res);
 3203                          5138                 :              3 :         return;
                               5139                 :                :     }
                               5140                 :                : 
                               5141                 :            185 :     query = createPQExpBuffer();
                               5142                 :                : 
                               5143                 :                :     /* Get the subscriptions in current database. */
 1147 drowley@postgresql.o     5144                 :            185 :     appendPQExpBufferStr(query,
                               5145                 :                :                          "SELECT s.tableoid, s.oid, s.subname,\n"
                               5146                 :                :                          " s.subowner,\n"
                               5147                 :                :                          " s.subconninfo, s.subslotname, s.subsynccommit,\n"
                               5148                 :                :                          " s.subpublications,\n");
                               5149                 :                : 
 1927 tgl@sss.pgh.pa.us        5150         [ +  - ]:            185 :     if (fout->remoteVersion >= 140000)
 1838 drowley@postgresql.o     5151                 :            185 :         appendPQExpBufferStr(query, " s.subbinary,\n");
                               5152                 :                :     else
 1838 drowley@postgresql.o     5153                 :UBC           0 :         appendPQExpBufferStr(query, " false AS subbinary,\n");
                               5154                 :                : 
 1880 akapila@postgresql.o     5155         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 140000)
 1566                          5156                 :            185 :         appendPQExpBufferStr(query, " s.substream,\n");
                               5157                 :                :     else
 1022 akapila@postgresql.o     5158                 :UBC           0 :         appendPQExpBufferStr(query, " 'f' AS substream,\n");
                               5159                 :                : 
 1566 akapila@postgresql.o     5160         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 150000)
 1323                          5161                 :            185 :         appendPQExpBufferStr(query,
                               5162                 :                :                              " s.subtwophasestate,\n"
                               5163                 :                :                              " s.subdisableonerr,\n");
                               5164                 :                :     else
 1566 akapila@postgresql.o     5165                 :UBC           0 :         appendPQExpBuffer(query,
                               5166                 :                :                           " '%c' AS subtwophasestate,\n"
                               5167                 :                :                           " false AS subdisableonerr,\n",
                               5168                 :                :                           LOGICALREP_TWOPHASE_STATE_DISABLED);
                               5169                 :                : 
 1194 akapila@postgresql.o     5170         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 160000)
  942 rhaas@postgresql.org     5171                 :            185 :         appendPQExpBufferStr(query,
                               5172                 :                :                              " s.subpasswordrequired,\n"
                               5173                 :                :                              " s.subrunasowner,\n"
                               5174                 :                :                              " s.suborigin,\n");
                               5175                 :                :     else
  942 rhaas@postgresql.org     5176                 :UBC           0 :         appendPQExpBuffer(query,
                               5177                 :                :                           " 't' AS subpasswordrequired,\n"
                               5178                 :                :                           " 't' AS subrunasowner,\n"
                               5179                 :                :                           " '%s' AS suborigin,\n",
                               5180                 :                :                           LOGICALREP_ORIGIN_ANY);
                               5181                 :                : 
  664 akapila@postgresql.o     5182   [ +  +  +  - ]:CBC         185 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5183                 :             36 :         appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
                               5184                 :                :                              " s.subenabled,\n");
                               5185                 :                :     else
                               5186                 :            149 :         appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
                               5187                 :                :                              " false AS subenabled,\n");
                               5188                 :                : 
  552                          5189         [ +  - ]:            185 :     if (fout->remoteVersion >= 170000)
                               5190                 :            185 :         appendPQExpBufferStr(query,
                               5191                 :                :                              " s.subfailover,\n");
                               5192                 :                :     else
  192 drowley@postgresql.o     5193                 :UNC           0 :         appendPQExpBufferStr(query,
                               5194                 :                :                              " false AS subfailover,\n");
                               5195                 :                : 
   96 akapila@postgresql.o     5196         [ +  - ]:GNC         185 :     if (fout->remoteVersion >= 190000)
                               5197                 :            185 :         appendPQExpBufferStr(query,
                               5198                 :                :                              " s.subretaindeadtuples,\n");
                               5199                 :                :     else
   96 akapila@postgresql.o     5200                 :UBC           0 :         appendPQExpBufferStr(query,
                               5201                 :                :                              " false AS subretaindeadtuples,\n");
                               5202                 :                : 
   55 akapila@postgresql.o     5203         [ +  - ]:GNC         185 :     if (fout->remoteVersion >= 190000)
                               5204                 :            185 :         appendPQExpBufferStr(query,
                               5205                 :                :                              " s.submaxretention\n");
                               5206                 :                :     else
   55 akapila@postgresql.o     5207                 :UNC           0 :         appendPQExpBuffer(query,
                               5208                 :                :                           " 0 AS submaxretention\n");
                               5209                 :                : 
  664 akapila@postgresql.o     5210                 :CBC         185 :     appendPQExpBufferStr(query,
                               5211                 :                :                          "FROM pg_subscription s\n");
                               5212                 :                : 
                               5213   [ +  +  +  - ]:            185 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5214                 :             36 :         appendPQExpBufferStr(query,
                               5215                 :                :                              "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
                               5216                 :                :                              "    ON o.external_id = 'pg_' || s.oid::text \n");
                               5217                 :                : 
 1838 drowley@postgresql.o     5218                 :            185 :     appendPQExpBufferStr(query,
                               5219                 :                :                          "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
                               5220                 :                :                          "                   WHERE datname = current_database())");
                               5221                 :                : 
 3203 peter_e@gmx.net          5222                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5223                 :                : 
                               5224                 :            185 :     ntups = PQntuples(res);
                               5225                 :                : 
                               5226                 :                :     /*
                               5227                 :                :      * Get subscription fields. We don't include subskiplsn in the dump as
                               5228                 :                :      * after restoring the dump this value may no longer be relevant.
                               5229                 :                :      */
                               5230                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               5231                 :            185 :     i_oid = PQfnumber(res, "oid");
                               5232                 :            185 :     i_subname = PQfnumber(res, "subname");
 1396 tgl@sss.pgh.pa.us        5233                 :            185 :     i_subowner = PQfnumber(res, "subowner");
  328 michael@paquier.xyz      5234                 :            185 :     i_subenabled = PQfnumber(res, "subenabled");
 1927 tgl@sss.pgh.pa.us        5235                 :            185 :     i_subbinary = PQfnumber(res, "subbinary");
 1880 akapila@postgresql.o     5236                 :            185 :     i_substream = PQfnumber(res, "substream");
 1566                          5237                 :            185 :     i_subtwophasestate = PQfnumber(res, "subtwophasestate");
 1323                          5238                 :            185 :     i_subdisableonerr = PQfnumber(res, "subdisableonerr");
  942 rhaas@postgresql.org     5239                 :            185 :     i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
  729 tgl@sss.pgh.pa.us        5240                 :            185 :     i_subrunasowner = PQfnumber(res, "subrunasowner");
  328 michael@paquier.xyz      5241                 :            185 :     i_subfailover = PQfnumber(res, "subfailover");
   96 akapila@postgresql.o     5242                 :GNC         185 :     i_subretaindeadtuples = PQfnumber(res, "subretaindeadtuples");
   55                          5243                 :            185 :     i_submaxretention = PQfnumber(res, "submaxretention");
  729 tgl@sss.pgh.pa.us        5244                 :CBC         185 :     i_subconninfo = PQfnumber(res, "subconninfo");
                               5245                 :            185 :     i_subslotname = PQfnumber(res, "subslotname");
                               5246                 :            185 :     i_subsynccommit = PQfnumber(res, "subsynccommit");
                               5247                 :            185 :     i_subpublications = PQfnumber(res, "subpublications");
                               5248                 :            185 :     i_suborigin = PQfnumber(res, "suborigin");
  664 akapila@postgresql.o     5249                 :            185 :     i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
                               5250                 :                : 
 3203 peter_e@gmx.net          5251                 :            185 :     subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
                               5252                 :                : 
                               5253         [ +  + ]:            313 :     for (i = 0; i < ntups; i++)
                               5254                 :                :     {
                               5255                 :            128 :         subinfo[i].dobj.objType = DO_SUBSCRIPTION;
                               5256                 :            128 :         subinfo[i].dobj.catId.tableoid =
                               5257                 :            128 :             atooid(PQgetvalue(res, i, i_tableoid));
                               5258                 :            128 :         subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5259                 :            128 :         AssignDumpId(&subinfo[i].dobj);
                               5260                 :            128 :         subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
 1396 tgl@sss.pgh.pa.us        5261                 :            128 :         subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
                               5262                 :                : 
  328 michael@paquier.xyz      5263                 :            128 :         subinfo[i].subenabled =
                               5264                 :            128 :             (strcmp(PQgetvalue(res, i, i_subenabled), "t") == 0);
 1927 tgl@sss.pgh.pa.us        5265                 :            128 :         subinfo[i].subbinary =
  328 michael@paquier.xyz      5266                 :            128 :             (strcmp(PQgetvalue(res, i, i_subbinary), "t") == 0);
                               5267                 :            128 :         subinfo[i].substream = *(PQgetvalue(res, i, i_substream));
                               5268                 :            128 :         subinfo[i].subtwophasestate = *(PQgetvalue(res, i, i_subtwophasestate));
 1323 akapila@postgresql.o     5269                 :            128 :         subinfo[i].subdisableonerr =
  328 michael@paquier.xyz      5270                 :            128 :             (strcmp(PQgetvalue(res, i, i_subdisableonerr), "t") == 0);
  942 rhaas@postgresql.org     5271                 :            128 :         subinfo[i].subpasswordrequired =
  328 michael@paquier.xyz      5272                 :            128 :             (strcmp(PQgetvalue(res, i, i_subpasswordrequired), "t") == 0);
  729 tgl@sss.pgh.pa.us        5273                 :            128 :         subinfo[i].subrunasowner =
  328 michael@paquier.xyz      5274                 :            128 :             (strcmp(PQgetvalue(res, i, i_subrunasowner), "t") == 0);
                               5275                 :            128 :         subinfo[i].subfailover =
                               5276                 :            128 :             (strcmp(PQgetvalue(res, i, i_subfailover), "t") == 0);
   96 akapila@postgresql.o     5277                 :GNC         128 :         subinfo[i].subretaindeadtuples =
                               5278                 :            128 :             (strcmp(PQgetvalue(res, i, i_subretaindeadtuples), "t") == 0);
   55                          5279                 :            128 :         subinfo[i].submaxretention =
                               5280                 :            128 :             atoi(PQgetvalue(res, i, i_submaxretention));
  729 tgl@sss.pgh.pa.us        5281                 :CBC         256 :         subinfo[i].subconninfo =
                               5282                 :            128 :             pg_strdup(PQgetvalue(res, i, i_subconninfo));
                               5283         [ -  + ]:            128 :         if (PQgetisnull(res, i, i_subslotname))
  729 tgl@sss.pgh.pa.us        5284                 :UBC           0 :             subinfo[i].subslotname = NULL;
                               5285                 :                :         else
  729 tgl@sss.pgh.pa.us        5286                 :CBC         128 :             subinfo[i].subslotname =
                               5287                 :            128 :                 pg_strdup(PQgetvalue(res, i, i_subslotname));
                               5288                 :            256 :         subinfo[i].subsynccommit =
                               5289                 :            128 :             pg_strdup(PQgetvalue(res, i, i_subsynccommit));
                               5290                 :            256 :         subinfo[i].subpublications =
                               5291                 :            128 :             pg_strdup(PQgetvalue(res, i, i_subpublications));
                               5292                 :            128 :         subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
  664 akapila@postgresql.o     5293         [ +  + ]:            128 :         if (PQgetisnull(res, i, i_suboriginremotelsn))
                               5294                 :            127 :             subinfo[i].suboriginremotelsn = NULL;
                               5295                 :                :         else
                               5296                 :              1 :             subinfo[i].suboriginremotelsn =
                               5297                 :              1 :                 pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
                               5298                 :                : 
                               5299                 :                :         /* Decide whether we want to dump it */
 3121 peter_e@gmx.net          5300                 :            128 :         selectDumpableObject(&(subinfo[i].dobj), fout);
                               5301                 :                :     }
 3203                          5302                 :            185 :     PQclear(res);
                               5303                 :                : 
                               5304                 :            185 :     destroyPQExpBuffer(query);
                               5305                 :                : }
                               5306                 :                : 
                               5307                 :                : /*
                               5308                 :                :  * getSubscriptionRelations
                               5309                 :                :  *    Get information about subscription membership for dumpable relations. This
                               5310                 :                :  *    will be used only in binary-upgrade mode for PG17 or later versions.
                               5311                 :                :  */
                               5312                 :                : void
   11 akapila@postgresql.o     5313                 :GNC         189 : getSubscriptionRelations(Archive *fout)
                               5314                 :                : {
  664 akapila@postgresql.o     5315                 :CBC         189 :     DumpOptions *dopt = fout->dopt;
                               5316                 :            189 :     SubscriptionInfo *subinfo = NULL;
                               5317                 :                :     SubRelInfo *subrinfo;
                               5318                 :                :     PGresult   *res;
                               5319                 :                :     int         i_srsubid;
                               5320                 :                :     int         i_srrelid;
                               5321                 :                :     int         i_srsubstate;
                               5322                 :                :     int         i_srsublsn;
                               5323                 :                :     int         ntups;
                               5324                 :            189 :     Oid         last_srsubid = InvalidOid;
                               5325                 :                : 
                               5326   [ +  +  +  + ]:            189 :     if (dopt->no_subscriptions || !dopt->binary_upgrade ||
                               5327         [ -  + ]:             36 :         fout->remoteVersion < 170000)
                               5328                 :            153 :         return;
                               5329                 :                : 
                               5330                 :             36 :     res = ExecuteSqlQuery(fout,
                               5331                 :                :                           "SELECT srsubid, srrelid, srsubstate, srsublsn "
                               5332                 :                :                           "FROM pg_catalog.pg_subscription_rel "
                               5333                 :                :                           "ORDER BY srsubid",
                               5334                 :                :                           PGRES_TUPLES_OK);
                               5335                 :             36 :     ntups = PQntuples(res);
                               5336         [ +  + ]:             36 :     if (ntups == 0)
                               5337                 :             35 :         goto cleanup;
                               5338                 :                : 
                               5339                 :                :     /* Get pg_subscription_rel attributes */
                               5340                 :              1 :     i_srsubid = PQfnumber(res, "srsubid");
                               5341                 :              1 :     i_srrelid = PQfnumber(res, "srrelid");
                               5342                 :              1 :     i_srsubstate = PQfnumber(res, "srsubstate");
                               5343                 :              1 :     i_srsublsn = PQfnumber(res, "srsublsn");
                               5344                 :                : 
                               5345                 :              1 :     subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
                               5346         [ +  + ]:              3 :     for (int i = 0; i < ntups; i++)
                               5347                 :                :     {
                               5348                 :              2 :         Oid         cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
                               5349                 :              2 :         Oid         relid = atooid(PQgetvalue(res, i, i_srrelid));
                               5350                 :                :         TableInfo  *tblinfo;
                               5351                 :                : 
                               5352                 :                :         /*
                               5353                 :                :          * If we switched to a new subscription, check if the subscription
                               5354                 :                :          * exists.
                               5355                 :                :          */
                               5356         [ +  - ]:              2 :         if (cur_srsubid != last_srsubid)
                               5357                 :                :         {
                               5358                 :              2 :             subinfo = findSubscriptionByOid(cur_srsubid);
                               5359         [ -  + ]:              2 :             if (subinfo == NULL)
  664 akapila@postgresql.o     5360                 :UBC           0 :                 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
                               5361                 :                : 
  664 akapila@postgresql.o     5362                 :CBC           2 :             last_srsubid = cur_srsubid;
                               5363                 :                :         }
                               5364                 :                : 
                               5365                 :              2 :         tblinfo = findTableByOid(relid);
                               5366         [ -  + ]:              2 :         if (tblinfo == NULL)
   11 akapila@postgresql.o     5367                 :UNC           0 :             pg_fatal("failed sanity check, relation with OID %u not found",
                               5368                 :                :                      relid);
                               5369                 :                : 
                               5370                 :                :         /* OK, make a DumpableObject for this relationship */
  664 akapila@postgresql.o     5371                 :CBC           2 :         subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
                               5372                 :              2 :         subrinfo[i].dobj.catId.tableoid = relid;
                               5373                 :              2 :         subrinfo[i].dobj.catId.oid = cur_srsubid;
                               5374                 :              2 :         AssignDumpId(&subrinfo[i].dobj);
                               5375                 :              2 :         subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
                               5376                 :              2 :         subrinfo[i].tblinfo = tblinfo;
                               5377                 :              2 :         subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
                               5378         [ +  + ]:              2 :         if (PQgetisnull(res, i, i_srsublsn))
                               5379                 :              1 :             subrinfo[i].srsublsn = NULL;
                               5380                 :                :         else
                               5381                 :              1 :             subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
                               5382                 :                : 
                               5383                 :              2 :         subrinfo[i].subinfo = subinfo;
                               5384                 :                : 
                               5385                 :                :         /* Decide whether we want to dump it */
                               5386                 :              2 :         selectDumpableObject(&(subrinfo[i].dobj), fout);
                               5387                 :                :     }
                               5388                 :                : 
                               5389                 :              1 : cleanup:
                               5390                 :             36 :     PQclear(res);
                               5391                 :                : }
                               5392                 :                : 
                               5393                 :                : /*
                               5394                 :                :  * dumpSubscriptionTable
                               5395                 :                :  *    Dump the definition of the given subscription table mapping. This will be
                               5396                 :                :  *    used only in binary-upgrade mode for PG17 or later versions.
                               5397                 :                :  */
                               5398                 :                : static void
                               5399                 :              2 : dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
                               5400                 :                : {
                               5401                 :              2 :     DumpOptions *dopt = fout->dopt;
                               5402                 :              2 :     SubscriptionInfo *subinfo = subrinfo->subinfo;
                               5403                 :                :     PQExpBuffer query;
                               5404                 :                :     char       *tag;
                               5405                 :                : 
                               5406                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     5407         [ -  + ]:              2 :     if (!dopt->dumpSchema)
  664 akapila@postgresql.o     5408                 :UBC           0 :         return;
                               5409                 :                : 
  664 akapila@postgresql.o     5410   [ +  -  +  - ]:CBC           2 :     Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
                               5411                 :                : 
                               5412                 :              2 :     tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
                               5413                 :                : 
                               5414                 :              2 :     query = createPQExpBuffer();
                               5415                 :                : 
                               5416         [ +  - ]:              2 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5417                 :                :     {
                               5418                 :                :         /*
                               5419                 :                :          * binary_upgrade_add_sub_rel_state will add the subscription relation
                               5420                 :                :          * to pg_subscription_rel table. This will be used only in
                               5421                 :                :          * binary-upgrade mode.
                               5422                 :                :          */
                               5423                 :              2 :         appendPQExpBufferStr(query,
                               5424                 :                :                              "\n-- For binary upgrade, must preserve the subscriber table.\n");
                               5425                 :              2 :         appendPQExpBufferStr(query,
                               5426                 :                :                              "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
                               5427                 :              2 :         appendStringLiteralAH(query, subrinfo->dobj.name, fout);
                               5428                 :              2 :         appendPQExpBuffer(query,
                               5429                 :                :                           ", %u, '%c'",
                               5430                 :              2 :                           subrinfo->tblinfo->dobj.catId.oid,
                               5431                 :              2 :                           subrinfo->srsubstate);
                               5432                 :                : 
                               5433   [ +  +  +  - ]:              2 :         if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
                               5434                 :              1 :             appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
                               5435                 :                :         else
  192 drowley@postgresql.o     5436                 :              1 :             appendPQExpBufferStr(query, ", NULL");
                               5437                 :                : 
  664 akapila@postgresql.o     5438                 :              2 :         appendPQExpBufferStr(query, ");\n");
                               5439                 :                :     }
                               5440                 :                : 
                               5441                 :                :     /*
                               5442                 :                :      * There is no point in creating a drop query as the drop is done by table
                               5443                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               5444                 :                :      * Although this object doesn't really have ownership as such, set the
                               5445                 :                :      * owner field anyway to ensure that the command is run by the correct
                               5446                 :                :      * role at restore time.
                               5447                 :                :      */
                               5448         [ +  - ]:              2 :     if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5449                 :              2 :         ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
                               5450                 :              2 :                      ARCHIVE_OPTS(.tag = tag,
                               5451                 :                :                                   .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
                               5452                 :                :                                   .owner = subinfo->rolname,
                               5453                 :                :                                   .description = "SUBSCRIPTION TABLE",
                               5454                 :                :                                   .section = SECTION_POST_DATA,
                               5455                 :                :                                   .createStmt = query->data));
                               5456                 :                : 
                               5457                 :                :     /* These objects can't currently have comments or seclabels */
                               5458                 :                : 
                               5459                 :              2 :     free(tag);
                               5460                 :              2 :     destroyPQExpBuffer(query);
                               5461                 :                : }
                               5462                 :                : 
                               5463                 :                : /*
                               5464                 :                :  * dumpSubscription
                               5465                 :                :  *    dump the definition of the given subscription
                               5466                 :                :  */
                               5467                 :                : static void
 1720 peter@eisentraut.org     5468                 :            110 : dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
                               5469                 :                : {
 1397 tgl@sss.pgh.pa.us        5470                 :            110 :     DumpOptions *dopt = fout->dopt;
                               5471                 :                :     PQExpBuffer delq;
                               5472                 :                :     PQExpBuffer query;
                               5473                 :                :     PQExpBuffer publications;
                               5474                 :                :     char       *qsubname;
 3203 peter_e@gmx.net          5475                 :            110 :     char      **pubnames = NULL;
                               5476                 :            110 :     int         npubnames = 0;
                               5477                 :                :     int         i;
                               5478                 :                : 
                               5479                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or     5480         [ +  + ]:            110 :     if (!dopt->dumpSchema)
 1397 tgl@sss.pgh.pa.us        5481                 :             18 :         return;
                               5482                 :                : 
 3203 peter_e@gmx.net          5483                 :             92 :     delq = createPQExpBuffer();
                               5484                 :             92 :     query = createPQExpBuffer();
                               5485                 :                : 
 2800 tgl@sss.pgh.pa.us        5486                 :             92 :     qsubname = pg_strdup(fmtId(subinfo->dobj.name));
                               5487                 :                : 
 3203 peter_e@gmx.net          5488                 :             92 :     appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
                               5489                 :                :                       qsubname);
                               5490                 :                : 
                               5491                 :             92 :     appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
                               5492                 :                :                       qsubname);
                               5493                 :             92 :     appendStringLiteralAH(query, subinfo->subconninfo, fout);
                               5494                 :                : 
                               5495                 :                :     /* Build list of quoted publications and append them to query. */
                               5496         [ -  + ]:             92 :     if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
 1298 tgl@sss.pgh.pa.us        5497                 :UBC           0 :         pg_fatal("could not parse %s array", "subpublications");
                               5498                 :                : 
 3203 peter_e@gmx.net          5499                 :CBC          92 :     publications = createPQExpBuffer();
                               5500         [ +  + ]:            184 :     for (i = 0; i < npubnames; i++)
                               5501                 :                :     {
                               5502         [ -  + ]:             92 :         if (i > 0)
 3203 peter_e@gmx.net          5503                 :UBC           0 :             appendPQExpBufferStr(publications, ", ");
                               5504                 :                : 
 3203 peter_e@gmx.net          5505                 :CBC          92 :         appendPQExpBufferStr(publications, fmtId(pubnames[i]));
                               5506                 :                :     }
                               5507                 :                : 
 3090                          5508                 :             92 :     appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
 3085                          5509         [ +  - ]:             92 :     if (subinfo->subslotname)
                               5510                 :             92 :         appendStringLiteralAH(query, subinfo->subslotname, fout);
                               5511                 :                :     else
 3085 peter_e@gmx.net          5512                 :UBC           0 :         appendPQExpBufferStr(query, "NONE");
                               5513                 :                : 
  328 michael@paquier.xyz      5514         [ -  + ]:CBC          92 :     if (subinfo->subbinary)
 1838 drowley@postgresql.o     5515                 :UBC           0 :         appendPQExpBufferStr(query, ", binary = true");
                               5516                 :                : 
  328 michael@paquier.xyz      5517         [ +  + ]:CBC          92 :     if (subinfo->substream == LOGICALREP_STREAM_ON)
 1838 drowley@postgresql.o     5518                 :             30 :         appendPQExpBufferStr(query, ", streaming = on");
  328 michael@paquier.xyz      5519         [ +  + ]:             62 :     else if (subinfo->substream == LOGICALREP_STREAM_PARALLEL)
 1022 akapila@postgresql.o     5520                 :             32 :         appendPQExpBufferStr(query, ", streaming = parallel");
                               5521                 :                :     else
  364                          5522                 :             30 :         appendPQExpBufferStr(query, ", streaming = off");
                               5523                 :                : 
  328 michael@paquier.xyz      5524         [ -  + ]:             92 :     if (subinfo->subtwophasestate != LOGICALREP_TWOPHASE_STATE_DISABLED)
 1566 akapila@postgresql.o     5525                 :UBC           0 :         appendPQExpBufferStr(query, ", two_phase = on");
                               5526                 :                : 
  328 michael@paquier.xyz      5527         [ -  + ]:CBC          92 :     if (subinfo->subdisableonerr)
 1323 akapila@postgresql.o     5528                 :UBC           0 :         appendPQExpBufferStr(query, ", disable_on_error = true");
                               5529                 :                : 
  328 michael@paquier.xyz      5530         [ -  + ]:CBC          92 :     if (!subinfo->subpasswordrequired)
  192 drowley@postgresql.o     5531                 :UBC           0 :         appendPQExpBufferStr(query, ", password_required = false");
                               5532                 :                : 
  328 michael@paquier.xyz      5533         [ -  + ]:CBC          92 :     if (subinfo->subrunasowner)
  729 tgl@sss.pgh.pa.us        5534                 :UBC           0 :         appendPQExpBufferStr(query, ", run_as_owner = true");
                               5535                 :                : 
  328 michael@paquier.xyz      5536         [ +  + ]:CBC          92 :     if (subinfo->subfailover)
  552 akapila@postgresql.o     5537                 :              1 :         appendPQExpBufferStr(query, ", failover = true");
                               5538                 :                : 
   96 akapila@postgresql.o     5539         [ +  + ]:GNC          92 :     if (subinfo->subretaindeadtuples)
                               5540                 :              1 :         appendPQExpBufferStr(query, ", retain_dead_tuples = true");
                               5541                 :                : 
   55                          5542         [ -  + ]:             92 :     if (subinfo->submaxretention)
   55 akapila@postgresql.o     5543                 :UNC           0 :         appendPQExpBuffer(query, ", max_retention_duration = %d", subinfo->submaxretention);
                               5544                 :                : 
 3118 peter_e@gmx.net          5545         [ -  + ]:CBC          92 :     if (strcmp(subinfo->subsynccommit, "off") != 0)
 3090 peter_e@gmx.net          5546                 :UBC           0 :         appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
                               5547                 :                : 
  729 tgl@sss.pgh.pa.us        5548         [ +  + ]:CBC          92 :     if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
                               5549                 :             30 :         appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
                               5550                 :                : 
 3203 peter_e@gmx.net          5551                 :             92 :     appendPQExpBufferStr(query, ");\n");
                               5552                 :                : 
                               5553                 :                :     /*
                               5554                 :                :      * In binary-upgrade mode, we allow the replication to continue after the
                               5555                 :                :      * upgrade.
                               5556                 :                :      */
  664 akapila@postgresql.o     5557   [ +  +  +  - ]:             92 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5558                 :                :     {
                               5559         [ +  + ]:              5 :         if (subinfo->suboriginremotelsn)
                               5560                 :                :         {
                               5561                 :                :             /*
                               5562                 :                :              * Preserve the remote_lsn for the subscriber's replication
                               5563                 :                :              * origin. This value is required to start the replication from
                               5564                 :                :              * the position before the upgrade. This value will be stale if
                               5565                 :                :              * the publisher gets upgraded before the subscriber node.
                               5566                 :                :              * However, this shouldn't be a problem as the upgrade of the
                               5567                 :                :              * publisher ensures that all the transactions were replicated
                               5568                 :                :              * before upgrading it.
                               5569                 :                :              */
                               5570                 :              1 :             appendPQExpBufferStr(query,
                               5571                 :                :                                  "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
                               5572                 :              1 :             appendPQExpBufferStr(query,
                               5573                 :                :                                  "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
                               5574                 :              1 :             appendStringLiteralAH(query, subinfo->dobj.name, fout);
                               5575                 :              1 :             appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
                               5576                 :                :         }
                               5577                 :                : 
  328 michael@paquier.xyz      5578         [ +  + ]:              5 :         if (subinfo->subenabled)
                               5579                 :                :         {
                               5580                 :                :             /*
                               5581                 :                :              * Enable the subscription to allow the replication to continue
                               5582                 :                :              * after the upgrade.
                               5583                 :                :              */
  664 akapila@postgresql.o     5584                 :              1 :             appendPQExpBufferStr(query,
                               5585                 :                :                                  "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
                               5586                 :              1 :             appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
                               5587                 :                :         }
                               5588                 :                :     }
                               5589                 :                : 
 1421 tgl@sss.pgh.pa.us        5590         [ +  - ]:             92 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5591                 :             92 :         ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
                               5592                 :             92 :                      ARCHIVE_OPTS(.tag = subinfo->dobj.name,
                               5593                 :                :                                   .owner = subinfo->rolname,
                               5594                 :                :                                   .description = "SUBSCRIPTION",
                               5595                 :                :                                   .section = SECTION_POST_DATA,
                               5596                 :                :                                   .createStmt = query->data,
                               5597                 :                :                                   .dropStmt = delq->data));
                               5598                 :                : 
 3119 peter_e@gmx.net          5599         [ +  + ]:             92 :     if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us        5600                 :             30 :         dumpComment(fout, "SUBSCRIPTION", qsubname,
 3119 peter_e@gmx.net          5601                 :             30 :                     NULL, subinfo->rolname,
                               5602                 :             30 :                     subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5603                 :                : 
                               5604         [ -  + ]:             92 :     if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us        5605                 :UBC           0 :         dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
 3119 peter_e@gmx.net          5606                 :              0 :                      NULL, subinfo->rolname,
                               5607                 :              0 :                      subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5608                 :                : 
 3203 peter_e@gmx.net          5609                 :CBC          92 :     destroyPQExpBuffer(publications);
 1229 peter@eisentraut.org     5610                 :             92 :     free(pubnames);
                               5611                 :                : 
 3203 peter_e@gmx.net          5612                 :             92 :     destroyPQExpBuffer(delq);
                               5613                 :             92 :     destroyPQExpBuffer(query);
 2800 tgl@sss.pgh.pa.us        5614                 :             92 :     free(qsubname);
                               5615                 :                : }
                               5616                 :                : 
                               5617                 :                : /*
                               5618                 :                :  * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
                               5619                 :                :  * the object needs.
                               5620                 :                :  */
                               5621                 :                : static void
 2056 alvherre@alvh.no-ip.     5622                 :           5043 : append_depends_on_extension(Archive *fout,
                               5623                 :                :                             PQExpBuffer create,
                               5624                 :                :                             const DumpableObject *dobj,
                               5625                 :                :                             const char *catalog,
                               5626                 :                :                             const char *keyword,
                               5627                 :                :                             const char *objname)
                               5628                 :                : {
                               5629         [ +  + ]:           5043 :     if (dobj->depends_on_ext)
                               5630                 :                :     {
                               5631                 :                :         char       *nm;
                               5632                 :                :         PGresult   *res;
                               5633                 :                :         PQExpBuffer query;
                               5634                 :                :         int         ntups;
                               5635                 :                :         int         i_extname;
                               5636                 :                :         int         i;
                               5637                 :                : 
                               5638                 :                :         /* dodge fmtId() non-reentrancy */
                               5639                 :             42 :         nm = pg_strdup(objname);
                               5640                 :                : 
                               5641                 :             42 :         query = createPQExpBuffer();
                               5642                 :             42 :         appendPQExpBuffer(query,
                               5643                 :                :                           "SELECT e.extname "
                               5644                 :                :                           "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
                               5645                 :                :                           "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
                               5646                 :                :                           "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
                               5647                 :                :                           "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
                               5648                 :                :                           catalog,
                               5649                 :             42 :                           dobj->catId.oid);
                               5650                 :             42 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5651                 :             42 :         ntups = PQntuples(res);
                               5652                 :             42 :         i_extname = PQfnumber(res, "extname");
                               5653         [ +  + ]:             84 :         for (i = 0; i < ntups; i++)
                               5654                 :                :         {
  794                          5655                 :             42 :             appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
                               5656                 :                :                               keyword, nm,
 2056                          5657                 :             42 :                               fmtId(PQgetvalue(res, i, i_extname)));
                               5658                 :                :         }
                               5659                 :                : 
                               5660                 :             42 :         PQclear(res);
 2051                          5661                 :             42 :         destroyPQExpBuffer(query);
 2056                          5662                 :             42 :         pg_free(nm);
                               5663                 :                :     }
                               5664                 :           5043 : }
                               5665                 :                : 
                               5666                 :                : static Oid
 1772 akorotkov@postgresql     5667                 :UBC           0 : get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
                               5668                 :                : {
                               5669                 :                :     /*
                               5670                 :                :      * If the old version didn't assign an array type, but the new version
                               5671                 :                :      * does, we must select an unused type OID to assign.  This currently only
                               5672                 :                :      * happens for domains, when upgrading pre-v11 to v11 and up.
                               5673                 :                :      *
                               5674                 :                :      * Note: local state here is kind of ugly, but we must have some, since we
                               5675                 :                :      * mustn't choose the same unused OID more than once.
                               5676                 :                :      */
                               5677                 :                :     static Oid  next_possible_free_oid = FirstNormalObjectId;
                               5678                 :                :     PGresult   *res;
                               5679                 :                :     bool        is_dup;
                               5680                 :                : 
                               5681                 :                :     do
                               5682                 :                :     {
                               5683                 :              0 :         ++next_possible_free_oid;
                               5684                 :              0 :         printfPQExpBuffer(upgrade_query,
                               5685                 :                :                           "SELECT EXISTS(SELECT 1 "
                               5686                 :                :                           "FROM pg_catalog.pg_type "
                               5687                 :                :                           "WHERE oid = '%u'::pg_catalog.oid);",
                               5688                 :                :                           next_possible_free_oid);
                               5689                 :              0 :         res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5690                 :              0 :         is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
                               5691                 :              0 :         PQclear(res);
                               5692         [ #  # ]:              0 :     } while (is_dup);
                               5693                 :                : 
                               5694                 :              0 :     return next_possible_free_oid;
                               5695                 :                : }
                               5696                 :                : 
                               5697                 :                : static void
 5011 rhaas@postgresql.org     5698                 :CBC         941 : binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                               5699                 :                :                                          PQExpBuffer upgrade_buffer,
                               5700                 :                :                                          Oid pg_type_oid,
                               5701                 :                :                                          bool force_array_type,
                               5702                 :                :                                          bool include_multirange_type)
                               5703                 :                : {
 5786 bruce@momjian.us         5704                 :            941 :     PQExpBuffer upgrade_query = createPQExpBuffer();
                               5705                 :                :     PGresult   *res;
                               5706                 :                :     Oid         pg_type_array_oid;
                               5707                 :                :     Oid         pg_type_multirange_oid;
                               5708                 :                :     Oid         pg_type_multirange_array_oid;
                               5709                 :                :     TypeInfo   *tinfo;
                               5710                 :                : 
 4361 heikki.linnakangas@i     5711                 :            941 :     appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
 5786 bruce@momjian.us         5712                 :            941 :     appendPQExpBuffer(upgrade_buffer,
                               5713                 :                :                       "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5714                 :                :                       pg_type_oid);
                               5715                 :                : 
  420 dgustafsson@postgres     5716                 :            941 :     tinfo = findTypeByOid(pg_type_oid);
  417                          5717         [ +  - ]:            941 :     if (tinfo)
                               5718                 :            941 :         pg_type_array_oid = tinfo->typarray;
                               5719                 :                :     else
  417 dgustafsson@postgres     5720                 :UBC           0 :         pg_type_array_oid = InvalidOid;
                               5721                 :                : 
 2949 tgl@sss.pgh.pa.us        5722   [ +  +  -  + ]:CBC         941 :     if (!OidIsValid(pg_type_array_oid) && force_array_type)
 1772 akorotkov@postgresql     5723                 :UBC           0 :         pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5724                 :                : 
 5786 bruce@momjian.us         5725         [ +  + ]:CBC         941 :     if (OidIsValid(pg_type_array_oid))
                               5726                 :                :     {
 4361 heikki.linnakangas@i     5727                 :            939 :         appendPQExpBufferStr(upgrade_buffer,
                               5728                 :                :                              "\n-- For binary upgrade, must preserve pg_type array oid\n");
 5786 bruce@momjian.us         5729                 :            939 :         appendPQExpBuffer(upgrade_buffer,
                               5730                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5731                 :                :                           pg_type_array_oid);
                               5732                 :                :     }
                               5733                 :                : 
                               5734                 :                :     /*
                               5735                 :                :      * Pre-set the multirange type oid and its own array type oid.
                               5736                 :                :      */
 1772 akorotkov@postgresql     5737         [ +  + ]:            941 :     if (include_multirange_type)
                               5738                 :                :     {
                               5739         [ +  - ]:              8 :         if (fout->remoteVersion >= 140000)
                               5740                 :                :         {
 1373 tgl@sss.pgh.pa.us        5741                 :              8 :             printfPQExpBuffer(upgrade_query,
                               5742                 :                :                               "SELECT t.oid, t.typarray "
                               5743                 :                :                               "FROM pg_catalog.pg_type t "
                               5744                 :                :                               "JOIN pg_catalog.pg_range r "
                               5745                 :                :                               "ON t.oid = r.rngmultitypid "
                               5746                 :                :                               "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
                               5747                 :                :                               pg_type_oid);
                               5748                 :                : 
 1772 akorotkov@postgresql     5749                 :              8 :             res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5750                 :                : 
                               5751                 :              8 :             pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
                               5752                 :              8 :             pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
                               5753                 :                : 
                               5754                 :              8 :             PQclear(res);
                               5755                 :                :         }
                               5756                 :                :         else
                               5757                 :                :         {
 1772 akorotkov@postgresql     5758                 :UBC           0 :             pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5759                 :              0 :             pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5760                 :                :         }
                               5761                 :                : 
 1772 akorotkov@postgresql     5762                 :CBC           8 :         appendPQExpBufferStr(upgrade_buffer,
                               5763                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
                               5764                 :              8 :         appendPQExpBuffer(upgrade_buffer,
                               5765                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5766                 :                :                           pg_type_multirange_oid);
                               5767                 :              8 :         appendPQExpBufferStr(upgrade_buffer,
                               5768                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
                               5769                 :              8 :         appendPQExpBuffer(upgrade_buffer,
                               5770                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5771                 :                :                           pg_type_multirange_array_oid);
                               5772                 :                :     }
                               5773                 :                : 
 5786 bruce@momjian.us         5774                 :            941 :     destroyPQExpBuffer(upgrade_query);
                               5775                 :            941 : }
                               5776                 :                : 
                               5777                 :                : static void
 1421 tgl@sss.pgh.pa.us        5778                 :            866 : binary_upgrade_set_type_oids_by_rel(Archive *fout,
                               5779                 :                :                                     PQExpBuffer upgrade_buffer,
                               5780                 :                :                                     const TableInfo *tbinfo)
                               5781                 :                : {
                               5782                 :            866 :     Oid         pg_type_oid = tbinfo->reltype;
                               5783                 :                : 
 1938                          5784         [ +  - ]:            866 :     if (OidIsValid(pg_type_oid))
                               5785                 :            866 :         binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
                               5786                 :                :                                                  pg_type_oid, false, false);
 5786 bruce@momjian.us         5787                 :            866 : }
                               5788                 :                : 
                               5789                 :                : /*
                               5790                 :                :  * bsearch() comparator for BinaryUpgradeClassOidItem
                               5791                 :                :  */
                               5792                 :                : static int
  481 nathan@postgresql.or     5793                 :          12363 : BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
                               5794                 :                : {
                               5795                 :          12363 :     BinaryUpgradeClassOidItem v1 = *((const BinaryUpgradeClassOidItem *) p1);
                               5796                 :          12363 :     BinaryUpgradeClassOidItem v2 = *((const BinaryUpgradeClassOidItem *) p2);
                               5797                 :                : 
                               5798                 :          12363 :     return pg_cmp_u32(v1.oid, v2.oid);
                               5799                 :                : }
                               5800                 :                : 
                               5801                 :                : /*
                               5802                 :                :  * collectBinaryUpgradeClassOids
                               5803                 :                :  *
                               5804                 :                :  * Construct a table of pg_class information required for
                               5805                 :                :  * binary_upgrade_set_pg_class_oids().  The table is sorted by OID for speed in
                               5806                 :                :  * lookup.
                               5807                 :                :  */
                               5808                 :                : static void
                               5809                 :             36 : collectBinaryUpgradeClassOids(Archive *fout)
                               5810                 :                : {
                               5811                 :                :     PGresult   *res;
                               5812                 :                :     const char *query;
                               5813                 :                : 
                               5814                 :             36 :     query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
                               5815                 :                :         "ct.relfilenode, i.indexrelid, cti.relfilenode "
                               5816                 :                :         "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
                               5817                 :                :         "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
                               5818                 :                :         "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
                               5819                 :                :         "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
                               5820                 :                :         "ORDER BY c.oid;";
                               5821                 :                : 
                               5822                 :             36 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                               5823                 :                : 
                               5824                 :             36 :     nbinaryUpgradeClassOids = PQntuples(res);
                               5825                 :             36 :     binaryUpgradeClassOids = (BinaryUpgradeClassOidItem *)
                               5826                 :             36 :         pg_malloc(nbinaryUpgradeClassOids * sizeof(BinaryUpgradeClassOidItem));
                               5827                 :                : 
                               5828         [ +  + ]:          16854 :     for (int i = 0; i < nbinaryUpgradeClassOids; i++)
                               5829                 :                :     {
                               5830                 :          16818 :         binaryUpgradeClassOids[i].oid = atooid(PQgetvalue(res, i, 0));
                               5831                 :          16818 :         binaryUpgradeClassOids[i].relkind = *PQgetvalue(res, i, 1);
                               5832                 :          16818 :         binaryUpgradeClassOids[i].relfilenumber = atooid(PQgetvalue(res, i, 2));
                               5833                 :          16818 :         binaryUpgradeClassOids[i].toast_oid = atooid(PQgetvalue(res, i, 3));
                               5834                 :          16818 :         binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
                               5835                 :          16818 :         binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5));
                               5836                 :          16818 :         binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6));
                               5837                 :                :     }
                               5838                 :                : 
                               5839                 :             36 :     PQclear(res);
                               5840                 :             36 : }
                               5841                 :                : 
                               5842                 :                : static void
 5011 rhaas@postgresql.org     5843                 :           1252 : binary_upgrade_set_pg_class_oids(Archive *fout,
                               5844                 :                :                                  PQExpBuffer upgrade_buffer, Oid pg_class_oid)
                               5845                 :                : {
  481 nathan@postgresql.or     5846                 :           1252 :     BinaryUpgradeClassOidItem key = {0};
                               5847                 :                :     BinaryUpgradeClassOidItem *entry;
                               5848                 :                : 
                               5849         [ -  + ]:           1252 :     Assert(binaryUpgradeClassOids);
                               5850                 :                : 
                               5851                 :                :     /*
                               5852                 :                :      * Preserve the OID and relfilenumber of the table, table's index, table's
                               5853                 :                :      * toast table and toast table's index if any.
                               5854                 :                :      *
                               5855                 :                :      * One complexity is that the current table definition might not require
                               5856                 :                :      * the creation of a TOAST table, but the old database might have a TOAST
                               5857                 :                :      * table that was created earlier, before some wide columns were dropped.
                               5858                 :                :      * By setting the TOAST oid we force creation of the TOAST heap and index
                               5859                 :                :      * by the new backend, so we can copy the files during binary upgrade
                               5860                 :                :      * without worrying about this case.
                               5861                 :                :      */
                               5862                 :           1252 :     key.oid = pg_class_oid;
                               5863                 :           1252 :     entry = bsearch(&key, binaryUpgradeClassOids, nbinaryUpgradeClassOids,
                               5864                 :                :                     sizeof(BinaryUpgradeClassOidItem),
                               5865                 :                :                     BinaryUpgradeClassOidItemCmp);
                               5866                 :                : 
 4361 heikki.linnakangas@i     5867                 :           1252 :     appendPQExpBufferStr(upgrade_buffer,
                               5868                 :                :                          "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
                               5869                 :                : 
  481 nathan@postgresql.or     5870         [ +  + ]:           1252 :     if (entry->relkind != RELKIND_INDEX &&
                               5871         [ +  + ]:            975 :         entry->relkind != RELKIND_PARTITIONED_INDEX)
                               5872                 :                :     {
 5773 bruce@momjian.us         5873                 :            950 :         appendPQExpBuffer(upgrade_buffer,
                               5874                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5875                 :                :                           pg_class_oid);
                               5876                 :                : 
                               5877                 :                :         /*
                               5878                 :                :          * Not every relation has storage. Also, in a pre-v12 database,
                               5879                 :                :          * partitioned tables have a relfilenumber, which should not be
                               5880                 :                :          * preserved when upgrading.
                               5881                 :                :          */
  481 nathan@postgresql.or     5882         [ +  + ]:            950 :         if (RelFileNumberIsValid(entry->relfilenumber) &&
                               5883         [ +  - ]:            788 :             entry->relkind != RELKIND_PARTITIONED_TABLE)
 1379 rhaas@postgresql.org     5884                 :            788 :             appendPQExpBuffer(upgrade_buffer,
                               5885                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               5886                 :                :                               entry->relfilenumber);
                               5887                 :                : 
                               5888                 :                :         /*
                               5889                 :                :          * In a pre-v12 database, partitioned tables might be marked as having
                               5890                 :                :          * toast tables, but we should ignore them if so.
                               5891                 :                :          */
  481 nathan@postgresql.or     5892         [ +  + ]:            950 :         if (OidIsValid(entry->toast_oid) &&
                               5893         [ +  - ]:            277 :             entry->relkind != RELKIND_PARTITIONED_TABLE)
                               5894                 :                :         {
 5409 bruce@momjian.us         5895                 :            277 :             appendPQExpBuffer(upgrade_buffer,
                               5896                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5897                 :                :                               entry->toast_oid);
 1379 rhaas@postgresql.org     5898                 :            277 :             appendPQExpBuffer(upgrade_buffer,
                               5899                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
                               5900                 :                :                               entry->toast_relfilenumber);
                               5901                 :                : 
                               5902                 :                :             /* every toast table has an index */
 5409 bruce@momjian.us         5903                 :            277 :             appendPQExpBuffer(upgrade_buffer,
                               5904                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5905                 :                :                               entry->toast_index_oid);
 1379 rhaas@postgresql.org     5906                 :            277 :             appendPQExpBuffer(upgrade_buffer,
                               5907                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5908                 :                :                               entry->toast_index_relfilenumber);
                               5909                 :                :         }
                               5910                 :                :     }
                               5911                 :                :     else
                               5912                 :                :     {
                               5913                 :                :         /* Preserve the OID and relfilenumber of the index */
 5773 bruce@momjian.us         5914                 :            302 :         appendPQExpBuffer(upgrade_buffer,
                               5915                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5916                 :                :                           pg_class_oid);
 1379 rhaas@postgresql.org     5917                 :            302 :         appendPQExpBuffer(upgrade_buffer,
                               5918                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5919                 :                :                           entry->relfilenumber);
                               5920                 :                :     }
                               5921                 :                : 
 4361 heikki.linnakangas@i     5922                 :           1252 :     appendPQExpBufferChar(upgrade_buffer, '\n');
 5786 bruce@momjian.us         5923                 :           1252 : }
                               5924                 :                : 
                               5925                 :                : /*
                               5926                 :                :  * If the DumpableObject is a member of an extension, add a suitable
                               5927                 :                :  * ALTER EXTENSION ADD command to the creation commands in upgrade_buffer.
                               5928                 :                :  *
                               5929                 :                :  * For somewhat historical reasons, objname should already be quoted,
                               5930                 :                :  * but not objnamespace (if any).
                               5931                 :                :  */
                               5932                 :                : static void
 5374 tgl@sss.pgh.pa.us        5933                 :           1502 : binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                               5934                 :                :                                 const DumpableObject *dobj,
                               5935                 :                :                                 const char *objtype,
                               5936                 :                :                                 const char *objname,
                               5937                 :                :                                 const char *objnamespace)
                               5938                 :                : {
                               5939                 :           1502 :     DumpableObject *extobj = NULL;
                               5940                 :                :     int         i;
                               5941                 :                : 
                               5942         [ +  + ]:           1502 :     if (!dobj->ext_member)
                               5943                 :           1481 :         return;
                               5944                 :                : 
                               5945                 :                :     /*
                               5946                 :                :      * Find the parent extension.  We could avoid this search if we wanted to
                               5947                 :                :      * add a link field to DumpableObject, but the space costs of that would
                               5948                 :                :      * be considerable.  We assume that member objects could only have a
                               5949                 :                :      * direct dependency on their own extension, not any others.
                               5950                 :                :      */
                               5951         [ +  - ]:             21 :     for (i = 0; i < dobj->nDeps; i++)
                               5952                 :                :     {
                               5953                 :             21 :         extobj = findObjectByDumpId(dobj->dependencies[i]);
                               5954   [ +  -  +  - ]:             21 :         if (extobj && extobj->objType == DO_EXTENSION)
                               5955                 :             21 :             break;
 5374 tgl@sss.pgh.pa.us        5956                 :UBC           0 :         extobj = NULL;
                               5957                 :                :     }
 5374 tgl@sss.pgh.pa.us        5958         [ -  + ]:CBC          21 :     if (extobj == NULL)
 1298 tgl@sss.pgh.pa.us        5959                 :UBC           0 :         pg_fatal("could not find parent extension for %s %s",
                               5960                 :                :                  objtype, objname);
                               5961                 :                : 
 4361 heikki.linnakangas@i     5962                 :CBC          21 :     appendPQExpBufferStr(upgrade_buffer,
                               5963                 :                :                          "\n-- For binary upgrade, handle extension membership the hard way\n");
 2800 tgl@sss.pgh.pa.us        5964                 :             21 :     appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
 5374                          5965                 :             21 :                       fmtId(extobj->name),
                               5966                 :                :                       objtype);
 2800                          5967   [ +  +  +  - ]:             21 :     if (objnamespace && *objnamespace)
                               5968                 :             18 :         appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
                               5969                 :             21 :     appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
                               5970                 :                : }
                               5971                 :                : 
                               5972                 :                : /*
                               5973                 :                :  * getNamespaces:
                               5974                 :                :  *    get information about all namespaces in the system catalogs
                               5975                 :                :  */
                               5976                 :                : void
  482 nathan@postgresql.or     5977                 :            190 : getNamespaces(Archive *fout)
                               5978                 :                : {
                               5979                 :                :     PGresult   *res;
                               5980                 :                :     int         ntups;
                               5981                 :                :     int         i;
                               5982                 :                :     PQExpBuffer query;
                               5983                 :                :     NamespaceInfo *nsinfo;
                               5984                 :                :     int         i_tableoid;
                               5985                 :                :     int         i_oid;
                               5986                 :                :     int         i_nspname;
                               5987                 :                :     int         i_nspowner;
                               5988                 :                :     int         i_nspacl;
                               5989                 :                :     int         i_acldefault;
                               5990                 :                : 
 8571 tgl@sss.pgh.pa.us        5991                 :            190 :     query = createPQExpBuffer();
                               5992                 :                : 
                               5993                 :                :     /*
                               5994                 :                :      * we fetch all namespaces including system ones, so that every object we
                               5995                 :                :      * read in can be linked to a containing namespace.
                               5996                 :                :      */
 1147 drowley@postgresql.o     5997                 :            190 :     appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
                               5998                 :                :                          "n.nspowner, "
                               5999                 :                :                          "n.nspacl, "
                               6000                 :                :                          "acldefault('n', n.nspowner) AS acldefault "
                               6001                 :                :                          "FROM pg_namespace n");
                               6002                 :                : 
 5011 rhaas@postgresql.org     6003                 :            190 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6004                 :                : 
10277 bruce@momjian.us         6005                 :            190 :     ntups = PQntuples(res);
                               6006                 :                : 
 5085                          6007                 :            190 :     nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
                               6008                 :                : 
 7996 tgl@sss.pgh.pa.us        6009                 :            190 :     i_tableoid = PQfnumber(res, "tableoid");
10277 bruce@momjian.us         6010                 :            190 :     i_oid = PQfnumber(res, "oid");
 8571 tgl@sss.pgh.pa.us        6011                 :            190 :     i_nspname = PQfnumber(res, "nspname");
 1582 noah@leadboat.com        6012                 :            190 :     i_nspowner = PQfnumber(res, "nspowner");
 8571 tgl@sss.pgh.pa.us        6013                 :            190 :     i_nspacl = PQfnumber(res, "nspacl");
 1421                          6014                 :            190 :     i_acldefault = PQfnumber(res, "acldefault");
                               6015                 :                : 
10277 bruce@momjian.us         6016         [ +  + ]:           1620 :     for (i = 0; i < ntups; i++)
                               6017                 :                :     {
                               6018                 :                :         const char *nspowner;
                               6019                 :                : 
 7996 tgl@sss.pgh.pa.us        6020                 :           1430 :         nsinfo[i].dobj.objType = DO_NAMESPACE;
                               6021                 :           1430 :         nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6022                 :           1430 :         nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6023                 :           1430 :         AssignDumpId(&nsinfo[i].dobj);
 5085 bruce@momjian.us         6024                 :           1430 :         nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
 1421 tgl@sss.pgh.pa.us        6025                 :           1430 :         nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
                               6026                 :           1430 :         nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6027                 :           1430 :         nsinfo[i].dacl.privtype = 0;
                               6028                 :           1430 :         nsinfo[i].dacl.initprivs = NULL;
 1396                          6029                 :           1430 :         nspowner = PQgetvalue(res, i, i_nspowner);
                               6030                 :           1430 :         nsinfo[i].nspowner = atooid(nspowner);
                               6031                 :           1430 :         nsinfo[i].rolname = getRoleName(nspowner);
                               6032                 :                : 
                               6033                 :                :         /* Decide whether to dump this namespace */
 3491 sfrost@snowman.net       6034                 :           1430 :         selectDumpableNamespace(&nsinfo[i], fout);
                               6035                 :                : 
                               6036                 :                :         /* Mark whether namespace has an ACL */
 1421 tgl@sss.pgh.pa.us        6037         [ +  + ]:           1430 :         if (!PQgetisnull(res, i, i_nspacl))
                               6038                 :            632 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6039                 :                : 
                               6040                 :                :         /*
                               6041                 :                :          * We ignore any pg_init_privs.initprivs entry for the public schema
                               6042                 :                :          * and assume a predetermined default, for several reasons.  First,
                               6043                 :                :          * dropping and recreating the schema removes its pg_init_privs entry,
                               6044                 :                :          * but an empty destination database starts with this ACL nonetheless.
                               6045                 :                :          * Second, we support dump/reload of public schema ownership changes.
                               6046                 :                :          * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
                               6047                 :                :          * initprivs continues to reflect the initial owner.  Hence,
                               6048                 :                :          * synthesize the value that nspacl will have after the restore's
                               6049                 :                :          * ALTER SCHEMA OWNER.  Third, this makes the destination database
                               6050                 :                :          * match the source's ACL, even if the latter was an initdb-default
                               6051                 :                :          * ACL, which changed in v15.  An upgrade pulls in changes to most
                               6052                 :                :          * system object ACLs that the DBA had not customized.  We've made the
                               6053                 :                :          * public schema depart from that, because changing its ACL so easily
                               6054                 :                :          * breaks applications.
                               6055                 :                :          */
                               6056         [ +  + ]:           1430 :         if (strcmp(nsinfo[i].dobj.name, "public") == 0)
                               6057                 :                :         {
                               6058                 :            186 :             PQExpBuffer aclarray = createPQExpBuffer();
                               6059                 :            186 :             PQExpBuffer aclitem = createPQExpBuffer();
                               6060                 :                : 
                               6061                 :                :             /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
                               6062                 :            186 :             appendPQExpBufferChar(aclarray, '{');
                               6063                 :            186 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               6064                 :            186 :             appendPQExpBufferStr(aclitem, "=UC/");
                               6065                 :            186 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               6066                 :            186 :             appendPGArray(aclarray, aclitem->data);
                               6067                 :            186 :             resetPQExpBuffer(aclitem);
                               6068                 :            186 :             appendPQExpBufferStr(aclitem, "=U/");
                               6069                 :            186 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               6070                 :            186 :             appendPGArray(aclarray, aclitem->data);
                               6071                 :            186 :             appendPQExpBufferChar(aclarray, '}');
                               6072                 :                : 
                               6073                 :            186 :             nsinfo[i].dacl.privtype = 'i';
                               6074                 :            186 :             nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
                               6075                 :            186 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6076                 :                : 
                               6077                 :            186 :             destroyPQExpBuffer(aclarray);
                               6078                 :            186 :             destroyPQExpBuffer(aclitem);
                               6079                 :                :         }
                               6080                 :                :     }
                               6081                 :                : 
10277 bruce@momjian.us         6082                 :            190 :     PQclear(res);
 8851 tgl@sss.pgh.pa.us        6083                 :            190 :     destroyPQExpBuffer(query);
10374 scrappy@hub.org          6084                 :            190 : }
                               6085                 :                : 
                               6086                 :                : /*
                               6087                 :                :  * findNamespace:
                               6088                 :                :  *      given a namespace OID, look up the info read by getNamespaces
                               6089                 :                :  */
                               6090                 :                : static NamespaceInfo *
 1889 peter@eisentraut.org     6091                 :         728510 : findNamespace(Oid nsoid)
                               6092                 :                : {
                               6093                 :                :     NamespaceInfo *nsinfo;
                               6094                 :                : 
 3302 tgl@sss.pgh.pa.us        6095                 :         728510 :     nsinfo = findNamespaceByOid(nsoid);
 4903                          6096         [ -  + ]:         728510 :     if (nsinfo == NULL)
 1298 tgl@sss.pgh.pa.us        6097                 :UBC           0 :         pg_fatal("schema with OID %u does not exist", nsoid);
 4903 tgl@sss.pgh.pa.us        6098                 :CBC      728510 :     return nsinfo;
                               6099                 :                : }
                               6100                 :                : 
                               6101                 :                : /*
                               6102                 :                :  * getExtensions:
                               6103                 :                :  *    read all extensions in the system catalogs and return them in the
                               6104                 :                :  * ExtensionInfo* structure
                               6105                 :                :  *
                               6106                 :                :  *  numExtensions is set to the number of extensions read in
                               6107                 :                :  */
                               6108                 :                : ExtensionInfo *
 3575                          6109                 :            190 : getExtensions(Archive *fout, int *numExtensions)
                               6110                 :                : {
                               6111                 :            190 :     DumpOptions *dopt = fout->dopt;
                               6112                 :                :     PGresult   *res;
                               6113                 :                :     int         ntups;
                               6114                 :                :     int         i;
                               6115                 :                :     PQExpBuffer query;
  390 dgustafsson@postgres     6116                 :            190 :     ExtensionInfo *extinfo = NULL;
                               6117                 :                :     int         i_tableoid;
                               6118                 :                :     int         i_oid;
                               6119                 :                :     int         i_extname;
                               6120                 :                :     int         i_nspname;
                               6121                 :                :     int         i_extrelocatable;
                               6122                 :                :     int         i_extversion;
                               6123                 :                :     int         i_extconfig;
                               6124                 :                :     int         i_extcondition;
                               6125                 :                : 
 5375 tgl@sss.pgh.pa.us        6126                 :            190 :     query = createPQExpBuffer();
                               6127                 :                : 
 4361 heikki.linnakangas@i     6128                 :            190 :     appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
                               6129                 :                :                          "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
                               6130                 :                :                          "FROM pg_extension x "
                               6131                 :                :                          "JOIN pg_namespace n ON n.oid = x.extnamespace");
                               6132                 :                : 
 5011 rhaas@postgresql.org     6133                 :            190 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6134                 :                : 
 5375 tgl@sss.pgh.pa.us        6135                 :            190 :     ntups = PQntuples(res);
  390 dgustafsson@postgres     6136         [ -  + ]:            190 :     if (ntups == 0)
  390 dgustafsson@postgres     6137                 :UBC           0 :         goto cleanup;
                               6138                 :                : 
 5085 bruce@momjian.us         6139                 :CBC         190 :     extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
                               6140                 :                : 
 5375 tgl@sss.pgh.pa.us        6141                 :            190 :     i_tableoid = PQfnumber(res, "tableoid");
                               6142                 :            190 :     i_oid = PQfnumber(res, "oid");
                               6143                 :            190 :     i_extname = PQfnumber(res, "extname");
                               6144                 :            190 :     i_nspname = PQfnumber(res, "nspname");
 5374                          6145                 :            190 :     i_extrelocatable = PQfnumber(res, "extrelocatable");
                               6146                 :            190 :     i_extversion = PQfnumber(res, "extversion");
 5375                          6147                 :            190 :     i_extconfig = PQfnumber(res, "extconfig");
                               6148                 :            190 :     i_extcondition = PQfnumber(res, "extcondition");
                               6149                 :                : 
                               6150         [ +  + ]:            410 :     for (i = 0; i < ntups; i++)
                               6151                 :                :     {
                               6152                 :            220 :         extinfo[i].dobj.objType = DO_EXTENSION;
                               6153                 :            220 :         extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6154                 :            220 :         extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6155                 :            220 :         AssignDumpId(&extinfo[i].dobj);
 5085 bruce@momjian.us         6156                 :            220 :         extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
                               6157                 :            220 :         extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
 5374 tgl@sss.pgh.pa.us        6158                 :            220 :         extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
 5085 bruce@momjian.us         6159                 :            220 :         extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
                               6160                 :            220 :         extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
                               6161                 :            220 :         extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
                               6162                 :                : 
                               6163                 :                :         /* Decide whether we want to dump it */
 3575 tgl@sss.pgh.pa.us        6164                 :            220 :         selectDumpableExtension(&(extinfo[i]), dopt);
                               6165                 :                :     }
                               6166                 :                : 
  390 dgustafsson@postgres     6167                 :            190 : cleanup:
 5375 tgl@sss.pgh.pa.us        6168                 :            190 :     PQclear(res);
                               6169                 :            190 :     destroyPQExpBuffer(query);
                               6170                 :                : 
                               6171                 :            190 :     *numExtensions = ntups;
                               6172                 :                : 
                               6173                 :            190 :     return extinfo;
                               6174                 :                : }
                               6175                 :                : 
                               6176                 :                : /*
                               6177                 :                :  * getTypes:
                               6178                 :                :  *    get information about all types in the system catalogs
                               6179                 :                :  *
                               6180                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               6181                 :                :  * findFuncByOid().
                               6182                 :                :  */
                               6183                 :                : void
  482 nathan@postgresql.or     6184                 :            189 : getTypes(Archive *fout)
                               6185                 :                : {
                               6186                 :                :     PGresult   *res;
                               6187                 :                :     int         ntups;
                               6188                 :                :     int         i;
 9329 bruce@momjian.us         6189                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               6190                 :                :     TypeInfo   *tyinfo;
                               6191                 :                :     ShellTypeInfo *stinfo;
                               6192                 :                :     int         i_tableoid;
                               6193                 :                :     int         i_oid;
                               6194                 :                :     int         i_typname;
                               6195                 :                :     int         i_typnamespace;
                               6196                 :                :     int         i_typacl;
                               6197                 :                :     int         i_acldefault;
                               6198                 :                :     int         i_typowner;
                               6199                 :                :     int         i_typelem;
                               6200                 :                :     int         i_typrelid;
                               6201                 :                :     int         i_typrelkind;
                               6202                 :                :     int         i_typtype;
                               6203                 :                :     int         i_typisdefined;
                               6204                 :                :     int         i_isarray;
                               6205                 :                :     int         i_typarray;
                               6206                 :                : 
                               6207                 :                :     /*
                               6208                 :                :      * we include even the built-in types because those may be used as array
                               6209                 :                :      * elements by user-defined types
                               6210                 :                :      *
                               6211                 :                :      * we filter out the built-in types when we dump out the types
                               6212                 :                :      *
                               6213                 :                :      * same approach for undefined (shell) types and array types
                               6214                 :                :      *
                               6215                 :                :      * Note: as of 8.3 we can reliably detect whether a type is an
                               6216                 :                :      * auto-generated array type by checking the element type's typarray.
                               6217                 :                :      * (Before that the test is capable of generating false positives.) We
                               6218                 :                :      * still check for name beginning with '_', though, so as to avoid the
                               6219                 :                :      * cost of the subselect probe for all standard types.  This would have to
                               6220                 :                :      * be revisited if the backend ever allows renaming of array types.
                               6221                 :                :      */
 1147 drowley@postgresql.o     6222                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
                               6223                 :                :                          "typnamespace, typacl, "
                               6224                 :                :                          "acldefault('T', typowner) AS acldefault, "
                               6225                 :                :                          "typowner, "
                               6226                 :                :                          "typelem, typrelid, typarray, "
                               6227                 :                :                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                               6228                 :                :                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
                               6229                 :                :                          "typtype, typisdefined, "
                               6230                 :                :                          "typname[0] = '_' AND typelem != 0 AND "
                               6231                 :                :                          "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
                               6232                 :                :                          "FROM pg_type");
                               6233                 :                : 
 5011 rhaas@postgresql.org     6234                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6235                 :                : 
10277 bruce@momjian.us         6236                 :            189 :     ntups = PQntuples(res);
                               6237                 :                : 
 5085                          6238                 :            189 :     tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
                               6239                 :                : 
 7996 tgl@sss.pgh.pa.us        6240                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
10277 bruce@momjian.us         6241                 :            189 :     i_oid = PQfnumber(res, "oid");
 8571 tgl@sss.pgh.pa.us        6242                 :            189 :     i_typname = PQfnumber(res, "typname");
                               6243                 :            189 :     i_typnamespace = PQfnumber(res, "typnamespace");
 4705                          6244                 :            189 :     i_typacl = PQfnumber(res, "typacl");
 1421                          6245                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
 1396                          6246                 :            189 :     i_typowner = PQfnumber(res, "typowner");
 8571                          6247                 :            189 :     i_typelem = PQfnumber(res, "typelem");
                               6248                 :            189 :     i_typrelid = PQfnumber(res, "typrelid");
 8474 bruce@momjian.us         6249                 :            189 :     i_typrelkind = PQfnumber(res, "typrelkind");
 8571 tgl@sss.pgh.pa.us        6250                 :            189 :     i_typtype = PQfnumber(res, "typtype");
                               6251                 :            189 :     i_typisdefined = PQfnumber(res, "typisdefined");
 6744                          6252                 :            189 :     i_isarray = PQfnumber(res, "isarray");
  420 dgustafsson@postgres     6253                 :            189 :     i_typarray = PQfnumber(res, "typarray");
                               6254                 :                : 
10277 bruce@momjian.us         6255         [ +  + ]:         136864 :     for (i = 0; i < ntups; i++)
                               6256                 :                :     {
 5787                          6257                 :         136675 :         tyinfo[i].dobj.objType = DO_TYPE;
                               6258                 :         136675 :         tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6259                 :         136675 :         tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6260                 :         136675 :         AssignDumpId(&tyinfo[i].dobj);
 5085                          6261                 :         136675 :         tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
 5012 rhaas@postgresql.org     6262                 :         273350 :         tyinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6263                 :         136675 :             findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
 1421 tgl@sss.pgh.pa.us        6264                 :         136675 :         tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
                               6265                 :         136675 :         tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6266                 :         136675 :         tyinfo[i].dacl.privtype = 0;
                               6267                 :         136675 :         tyinfo[i].dacl.initprivs = NULL;
 1518                          6268                 :         136675 :         tyinfo[i].ftypname = NULL;  /* may get filled later */
 1396                          6269                 :         136675 :         tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
 5787 bruce@momjian.us         6270                 :         136675 :         tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
                               6271                 :         136675 :         tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
                               6272                 :         136675 :         tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
                               6273                 :         136675 :         tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
                               6274                 :         136675 :         tyinfo[i].shellType = NULL;
                               6275                 :                : 
 8571 tgl@sss.pgh.pa.us        6276         [ +  + ]:         136675 :         if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
 5787 bruce@momjian.us         6277                 :         136623 :             tyinfo[i].isDefined = true;
                               6278                 :                :         else
                               6279                 :             52 :             tyinfo[i].isDefined = false;
                               6280                 :                : 
 6744 tgl@sss.pgh.pa.us        6281         [ +  + ]:         136675 :         if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
 5787 bruce@momjian.us         6282                 :          65571 :             tyinfo[i].isArray = true;
                               6283                 :                :         else
                               6284                 :          71104 :             tyinfo[i].isArray = false;
                               6285                 :                : 
  420 dgustafsson@postgres     6286                 :         136675 :         tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
                               6287                 :                : 
  621 tgl@sss.pgh.pa.us        6288         [ +  + ]:         136675 :         if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
 1772 akorotkov@postgresql     6289                 :           1266 :             tyinfo[i].isMultirange = true;
                               6290                 :                :         else
                               6291                 :         135409 :             tyinfo[i].isMultirange = false;
                               6292                 :                : 
                               6293                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6294                 :         136675 :         selectDumpableType(&tyinfo[i], fout);
                               6295                 :                : 
                               6296                 :                :         /* Mark whether type has an ACL */
 1421 tgl@sss.pgh.pa.us        6297         [ +  + ]:         136675 :         if (!PQgetisnull(res, i, i_typacl))
                               6298                 :            205 :             tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6299                 :                : 
                               6300                 :                :         /*
                               6301                 :                :          * If it's a domain, fetch info about its constraints, if any
                               6302                 :                :          */
 5787 bruce@momjian.us         6303                 :         136675 :         tyinfo[i].nDomChecks = 0;
                               6304                 :         136675 :         tyinfo[i].domChecks = NULL;
   98 alvherre@kurilemu.de     6305                 :         136675 :         tyinfo[i].notnull = NULL;
 3491 sfrost@snowman.net       6306         [ +  + ]:         136675 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               6307         [ +  + ]:          14965 :             tyinfo[i].typtype == TYPTYPE_DOMAIN)
 5012 rhaas@postgresql.org     6308                 :            158 :             getDomainConstraints(fout, &(tyinfo[i]));
                               6309                 :                : 
                               6310                 :                :         /*
                               6311                 :                :          * If it's a base type, make a DumpableObject representing a shell
                               6312                 :                :          * definition of the type.  We will need to dump that ahead of the I/O
                               6313                 :                :          * functions for the type.  Similarly, range types need a shell
                               6314                 :                :          * definition in case they have a canonicalize function.
                               6315                 :                :          *
                               6316                 :                :          * Note: the shell type doesn't have a catId.  You might think it
                               6317                 :                :          * should copy the base type's catId, but then it might capture the
                               6318                 :                :          * pg_depend entries for the type, which we don't want.
                               6319                 :                :          */
 3491 sfrost@snowman.net       6320         [ +  + ]:         136675 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               6321         [ +  + ]:          14965 :             (tyinfo[i].typtype == TYPTYPE_BASE ||
                               6322         [ +  + ]:           7269 :              tyinfo[i].typtype == TYPTYPE_RANGE))
                               6323                 :                :         {
 5085 bruce@momjian.us         6324                 :           7820 :             stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
 7179 tgl@sss.pgh.pa.us        6325                 :           7820 :             stinfo->dobj.objType = DO_SHELL_TYPE;
                               6326                 :           7820 :             stinfo->dobj.catId = nilCatalogId;
                               6327                 :           7820 :             AssignDumpId(&stinfo->dobj);
 5085 bruce@momjian.us         6328                 :           7820 :             stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
 5787                          6329                 :           7820 :             stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
                               6330                 :           7820 :             stinfo->baseType = &(tyinfo[i]);
                               6331                 :           7820 :             tyinfo[i].shellType = stinfo;
                               6332                 :                : 
                               6333                 :                :             /*
                               6334                 :                :              * Initially mark the shell type as not to be dumped.  We'll only
                               6335                 :                :              * dump it if the I/O or canonicalize functions need to be dumped;
                               6336                 :                :              * this is taken care of while sorting dependencies.
                               6337                 :                :              */
 3491 sfrost@snowman.net       6338                 :           7820 :             stinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               6339                 :                :         }
                               6340                 :                :     }
                               6341                 :                : 
10277 bruce@momjian.us         6342                 :            189 :     PQclear(res);
                               6343                 :                : 
 8851 tgl@sss.pgh.pa.us        6344                 :            189 :     destroyPQExpBuffer(query);
10702 scrappy@hub.org          6345                 :            189 : }
                               6346                 :                : 
                               6347                 :                : /*
                               6348                 :                :  * getOperators:
                               6349                 :                :  *    get information about all operators in the system catalogs
                               6350                 :                :  */
                               6351                 :                : void
  482 nathan@postgresql.or     6352                 :            189 : getOperators(Archive *fout)
                               6353                 :                : {
                               6354                 :                :     PGresult   *res;
                               6355                 :                :     int         ntups;
                               6356                 :                :     int         i;
 9329 bruce@momjian.us         6357                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               6358                 :                :     OprInfo    *oprinfo;
                               6359                 :                :     int         i_tableoid;
                               6360                 :                :     int         i_oid;
                               6361                 :                :     int         i_oprname;
                               6362                 :                :     int         i_oprnamespace;
                               6363                 :                :     int         i_oprowner;
                               6364                 :                :     int         i_oprkind;
                               6365                 :                :     int         i_oprleft;
                               6366                 :                :     int         i_oprright;
                               6367                 :                :     int         i_oprcode;
                               6368                 :                : 
                               6369                 :                :     /*
                               6370                 :                :      * find all operators, including builtin operators; we filter out
                               6371                 :                :      * system-defined operators at dump-out time.
                               6372                 :                :      */
                               6373                 :                : 
 1147 drowley@postgresql.o     6374                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
                               6375                 :                :                          "oprnamespace, "
                               6376                 :                :                          "oprowner, "
                               6377                 :                :                          "oprkind, "
                               6378                 :                :                          "oprleft, "
                               6379                 :                :                          "oprright, "
                               6380                 :                :                          "oprcode::oid AS oprcode "
                               6381                 :                :                          "FROM pg_operator");
                               6382                 :                : 
 5011 rhaas@postgresql.org     6383                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6384                 :                : 
10277 bruce@momjian.us         6385                 :            189 :     ntups = PQntuples(res);
                               6386                 :                : 
 5085                          6387                 :            189 :     oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
                               6388                 :                : 
 7996 tgl@sss.pgh.pa.us        6389                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
10277 bruce@momjian.us         6390                 :            189 :     i_oid = PQfnumber(res, "oid");
 8571 tgl@sss.pgh.pa.us        6391                 :            189 :     i_oprname = PQfnumber(res, "oprname");
                               6392                 :            189 :     i_oprnamespace = PQfnumber(res, "oprnamespace");
 1396                          6393                 :            189 :     i_oprowner = PQfnumber(res, "oprowner");
 5044 peter_e@gmx.net          6394                 :            189 :     i_oprkind = PQfnumber(res, "oprkind");
   88 noah@leadboat.com        6395                 :            189 :     i_oprleft = PQfnumber(res, "oprleft");
                               6396                 :            189 :     i_oprright = PQfnumber(res, "oprright");
 8571 tgl@sss.pgh.pa.us        6397                 :            189 :     i_oprcode = PQfnumber(res, "oprcode");
                               6398                 :                : 
10277 bruce@momjian.us         6399         [ +  + ]:         151342 :     for (i = 0; i < ntups; i++)
                               6400                 :                :     {
 7996 tgl@sss.pgh.pa.us        6401                 :         151153 :         oprinfo[i].dobj.objType = DO_OPERATOR;
                               6402                 :         151153 :         oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6403                 :         151153 :         oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6404                 :         151153 :         AssignDumpId(&oprinfo[i].dobj);
 5085 bruce@momjian.us         6405                 :         151153 :         oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
 5012 rhaas@postgresql.org     6406                 :         302306 :         oprinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6407                 :         151153 :             findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
 1396 tgl@sss.pgh.pa.us        6408                 :         151153 :         oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
 5044 peter_e@gmx.net          6409                 :         151153 :         oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
   88 noah@leadboat.com        6410                 :         151153 :         oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
                               6411                 :         151153 :         oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
 7996 tgl@sss.pgh.pa.us        6412                 :         151153 :         oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
                               6413                 :                : 
                               6414                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6415                 :         151153 :         selectDumpableObject(&(oprinfo[i].dobj), fout);
                               6416                 :                :     }
                               6417                 :                : 
10277 bruce@momjian.us         6418                 :            189 :     PQclear(res);
                               6419                 :                : 
 8851 tgl@sss.pgh.pa.us        6420                 :            189 :     destroyPQExpBuffer(query);
10702 scrappy@hub.org          6421                 :            189 : }
                               6422                 :                : 
                               6423                 :                : /*
                               6424                 :                :  * getCollations:
                               6425                 :                :  *    get information about all collations in the system catalogs
                               6426                 :                :  */
                               6427                 :                : void
  482 nathan@postgresql.or     6428                 :            189 : getCollations(Archive *fout)
                               6429                 :                : {
                               6430                 :                :     PGresult   *res;
                               6431                 :                :     int         ntups;
                               6432                 :                :     int         i;
                               6433                 :                :     PQExpBuffer query;
                               6434                 :                :     CollInfo   *collinfo;
                               6435                 :                :     int         i_tableoid;
                               6436                 :                :     int         i_oid;
                               6437                 :                :     int         i_collname;
                               6438                 :                :     int         i_collnamespace;
                               6439                 :                :     int         i_collowner;
                               6440                 :                :     int         i_collencoding;
                               6441                 :                : 
 4976 peter_e@gmx.net          6442                 :            189 :     query = createPQExpBuffer();
                               6443                 :                : 
                               6444                 :                :     /*
                               6445                 :                :      * find all collations, including builtin collations; we filter out
                               6446                 :                :      * system-defined collations at dump-out time.
                               6447                 :                :      */
                               6448                 :                : 
 1147 drowley@postgresql.o     6449                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
                               6450                 :                :                          "collnamespace, "
                               6451                 :                :                          "collowner, "
                               6452                 :                :                          "collencoding "
                               6453                 :                :                          "FROM pg_collation");
                               6454                 :                : 
 5011 rhaas@postgresql.org     6455                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6456                 :                : 
 5371 peter_e@gmx.net          6457                 :            189 :     ntups = PQntuples(res);
                               6458                 :                : 
 5085 bruce@momjian.us         6459                 :            189 :     collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
                               6460                 :                : 
 5371 peter_e@gmx.net          6461                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               6462                 :            189 :     i_oid = PQfnumber(res, "oid");
                               6463                 :            189 :     i_collname = PQfnumber(res, "collname");
                               6464                 :            189 :     i_collnamespace = PQfnumber(res, "collnamespace");
 1396 tgl@sss.pgh.pa.us        6465                 :            189 :     i_collowner = PQfnumber(res, "collowner");
   88 noah@leadboat.com        6466                 :            189 :     i_collencoding = PQfnumber(res, "collencoding");
                               6467                 :                : 
 5371 peter_e@gmx.net          6468         [ +  + ]:         287202 :     for (i = 0; i < ntups; i++)
                               6469                 :                :     {
                               6470                 :         287013 :         collinfo[i].dobj.objType = DO_COLLATION;
                               6471                 :         287013 :         collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6472                 :         287013 :         collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6473                 :         287013 :         AssignDumpId(&collinfo[i].dobj);
 5085 bruce@momjian.us         6474                 :         287013 :         collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
 5012 rhaas@postgresql.org     6475                 :         574026 :         collinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6476                 :         287013 :             findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
 1396 tgl@sss.pgh.pa.us        6477                 :         287013 :         collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
   88 noah@leadboat.com        6478                 :         287013 :         collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
                               6479                 :                : 
                               6480                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6481                 :         287013 :         selectDumpableObject(&(collinfo[i].dobj), fout);
                               6482                 :                :     }
                               6483                 :                : 
 5371 peter_e@gmx.net          6484                 :            189 :     PQclear(res);
                               6485                 :                : 
                               6486                 :            189 :     destroyPQExpBuffer(query);
                               6487                 :            189 : }
                               6488                 :                : 
                               6489                 :                : /*
                               6490                 :                :  * getConversions:
                               6491                 :                :  *    get information about all conversions in the system catalogs
                               6492                 :                :  */
                               6493                 :                : void
  482 nathan@postgresql.or     6494                 :            189 : getConversions(Archive *fout)
                               6495                 :                : {
                               6496                 :                :     PGresult   *res;
                               6497                 :                :     int         ntups;
                               6498                 :                :     int         i;
                               6499                 :                :     PQExpBuffer query;
                               6500                 :                :     ConvInfo   *convinfo;
                               6501                 :                :     int         i_tableoid;
                               6502                 :                :     int         i_oid;
                               6503                 :                :     int         i_conname;
                               6504                 :                :     int         i_connamespace;
                               6505                 :                :     int         i_conowner;
                               6506                 :                : 
 4292 sfrost@snowman.net       6507                 :            189 :     query = createPQExpBuffer();
                               6508                 :                : 
                               6509                 :                :     /*
                               6510                 :                :      * find all conversions, including builtin conversions; we filter out
                               6511                 :                :      * system-defined conversions at dump-out time.
                               6512                 :                :      */
                               6513                 :                : 
 1147 drowley@postgresql.o     6514                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
                               6515                 :                :                          "connamespace, "
                               6516                 :                :                          "conowner "
                               6517                 :                :                          "FROM pg_conversion");
                               6518                 :                : 
 5011 rhaas@postgresql.org     6519                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6520                 :                : 
 8011 tgl@sss.pgh.pa.us        6521                 :            189 :     ntups = PQntuples(res);
                               6522                 :                : 
 5085 bruce@momjian.us         6523                 :            189 :     convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
                               6524                 :                : 
 7996 tgl@sss.pgh.pa.us        6525                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 8011                          6526                 :            189 :     i_oid = PQfnumber(res, "oid");
                               6527                 :            189 :     i_conname = PQfnumber(res, "conname");
                               6528                 :            189 :     i_connamespace = PQfnumber(res, "connamespace");
 1396                          6529                 :            189 :     i_conowner = PQfnumber(res, "conowner");
                               6530                 :                : 
 8011                          6531         [ +  + ]:          24426 :     for (i = 0; i < ntups; i++)
                               6532                 :                :     {
 7996                          6533                 :          24237 :         convinfo[i].dobj.objType = DO_CONVERSION;
                               6534                 :          24237 :         convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6535                 :          24237 :         convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6536                 :          24237 :         AssignDumpId(&convinfo[i].dobj);
 5085 bruce@momjian.us         6537                 :          24237 :         convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 5012 rhaas@postgresql.org     6538                 :          48474 :         convinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6539                 :          24237 :             findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
 1396 tgl@sss.pgh.pa.us        6540                 :          24237 :         convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
                               6541                 :                : 
                               6542                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6543                 :          24237 :         selectDumpableObject(&(convinfo[i].dobj), fout);
                               6544                 :                :     }
                               6545                 :                : 
 8011 tgl@sss.pgh.pa.us        6546                 :            189 :     PQclear(res);
                               6547                 :                : 
                               6548                 :            189 :     destroyPQExpBuffer(query);
                               6549                 :            189 : }
                               6550                 :                : 
                               6551                 :                : /*
                               6552                 :                :  * getAccessMethods:
                               6553                 :                :  *    get information about all user-defined access methods
                               6554                 :                :  */
                               6555                 :                : void
  482 nathan@postgresql.or     6556                 :            189 : getAccessMethods(Archive *fout)
                               6557                 :                : {
                               6558                 :                :     PGresult   *res;
                               6559                 :                :     int         ntups;
                               6560                 :                :     int         i;
                               6561                 :                :     PQExpBuffer query;
                               6562                 :                :     AccessMethodInfo *aminfo;
                               6563                 :                :     int         i_tableoid;
                               6564                 :                :     int         i_oid;
                               6565                 :                :     int         i_amname;
                               6566                 :                :     int         i_amhandler;
                               6567                 :                :     int         i_amtype;
                               6568                 :                : 
 3505 alvherre@alvh.no-ip.     6569                 :            189 :     query = createPQExpBuffer();
                               6570                 :                : 
                               6571                 :                :     /*
                               6572                 :                :      * Select all access methods from pg_am table.  v9.6 introduced CREATE
                               6573                 :                :      * ACCESS METHOD, so earlier versions usually have only built-in access
                               6574                 :                :      * methods.  v9.6 also changed the access method API, replacing dozens of
                               6575                 :                :      * pg_am columns with amhandler.  Even if a user created an access method
                               6576                 :                :      * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am
                               6577                 :                :      * columns to a v9.6+ CREATE ACCESS METHOD.  Hence, before v9.6, read
                               6578                 :                :      * pg_am just to facilitate findAccessMethodByOid() providing the
                               6579                 :                :      * OID-to-name mapping.
                               6580                 :                :      */
   88 noah@leadboat.com        6581                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, ");
                               6582         [ +  - ]:            189 :     if (fout->remoteVersion >= 90600)
                               6583                 :            189 :         appendPQExpBufferStr(query,
                               6584                 :                :                              "amtype, "
                               6585                 :                :                              "amhandler::pg_catalog.regproc AS amhandler ");
                               6586                 :                :     else
   88 noah@leadboat.com        6587                 :UBC           0 :         appendPQExpBufferStr(query,
                               6588                 :                :                              "'i'::pg_catalog.\"char\" AS amtype, "
                               6589                 :                :                              "'-'::pg_catalog.regproc AS amhandler ");
   88 noah@leadboat.com        6590                 :CBC         189 :     appendPQExpBufferStr(query, "FROM pg_am");
                               6591                 :                : 
 3505 alvherre@alvh.no-ip.     6592                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6593                 :                : 
                               6594                 :            189 :     ntups = PQntuples(res);
                               6595                 :                : 
                               6596                 :            189 :     aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
                               6597                 :                : 
                               6598                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               6599                 :            189 :     i_oid = PQfnumber(res, "oid");
                               6600                 :            189 :     i_amname = PQfnumber(res, "amname");
                               6601                 :            189 :     i_amhandler = PQfnumber(res, "amhandler");
                               6602                 :            189 :     i_amtype = PQfnumber(res, "amtype");
                               6603                 :                : 
                               6604         [ +  + ]:           1634 :     for (i = 0; i < ntups; i++)
                               6605                 :                :     {
                               6606                 :           1445 :         aminfo[i].dobj.objType = DO_ACCESS_METHOD;
                               6607                 :           1445 :         aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6608                 :           1445 :         aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6609                 :           1445 :         AssignDumpId(&aminfo[i].dobj);
                               6610                 :           1445 :         aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
                               6611                 :           1445 :         aminfo[i].dobj.namespace = NULL;
                               6612                 :           1445 :         aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
                               6613                 :           1445 :         aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
                               6614                 :                : 
                               6615                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6616                 :           1445 :         selectDumpableAccessMethod(&(aminfo[i]), fout);
                               6617                 :                :     }
                               6618                 :                : 
 3505 alvherre@alvh.no-ip.     6619                 :            189 :     PQclear(res);
                               6620                 :                : 
                               6621                 :            189 :     destroyPQExpBuffer(query);
                               6622                 :            189 : }
                               6623                 :                : 
                               6624                 :                : 
                               6625                 :                : /*
                               6626                 :                :  * getOpclasses:
                               6627                 :                :  *    get information about all opclasses in the system catalogs
                               6628                 :                :  */
                               6629                 :                : void
  482 nathan@postgresql.or     6630                 :            189 : getOpclasses(Archive *fout)
                               6631                 :                : {
                               6632                 :                :     PGresult   *res;
                               6633                 :                :     int         ntups;
                               6634                 :                :     int         i;
 8490 tgl@sss.pgh.pa.us        6635                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               6636                 :                :     OpclassInfo *opcinfo;
                               6637                 :                :     int         i_tableoid;
                               6638                 :                :     int         i_oid;
                               6639                 :                :     int         i_opcmethod;
                               6640                 :                :     int         i_opcname;
                               6641                 :                :     int         i_opcnamespace;
                               6642                 :                :     int         i_opcowner;
                               6643                 :                : 
                               6644                 :                :     /*
                               6645                 :                :      * find all opclasses, including builtin opclasses; we filter out
                               6646                 :                :      * system-defined opclasses at dump-out time.
                               6647                 :                :      */
                               6648                 :                : 
   88 noah@leadboat.com        6649                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opcmethod, opcname, "
                               6650                 :                :                          "opcnamespace, "
                               6651                 :                :                          "opcowner "
                               6652                 :                :                          "FROM pg_opclass");
                               6653                 :                : 
 5011 rhaas@postgresql.org     6654                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6655                 :                : 
 8490 tgl@sss.pgh.pa.us        6656                 :            189 :     ntups = PQntuples(res);
                               6657                 :                : 
 5085 bruce@momjian.us         6658                 :            189 :     opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
                               6659                 :                : 
 7996 tgl@sss.pgh.pa.us        6660                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 8490                          6661                 :            189 :     i_oid = PQfnumber(res, "oid");
   88 noah@leadboat.com        6662                 :            189 :     i_opcmethod = PQfnumber(res, "opcmethod");
 8490 tgl@sss.pgh.pa.us        6663                 :            189 :     i_opcname = PQfnumber(res, "opcname");
                               6664                 :            189 :     i_opcnamespace = PQfnumber(res, "opcnamespace");
 1396                          6665                 :            189 :     i_opcowner = PQfnumber(res, "opcowner");
                               6666                 :                : 
 8490                          6667         [ +  + ]:          33798 :     for (i = 0; i < ntups; i++)
                               6668                 :                :     {
 7996                          6669                 :          33609 :         opcinfo[i].dobj.objType = DO_OPCLASS;
                               6670                 :          33609 :         opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6671                 :          33609 :         opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6672                 :          33609 :         AssignDumpId(&opcinfo[i].dobj);
 5085 bruce@momjian.us         6673                 :          33609 :         opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
 5012 rhaas@postgresql.org     6674                 :          67218 :         opcinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6675                 :          33609 :             findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
   88 noah@leadboat.com        6676                 :          33609 :         opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
 1396 tgl@sss.pgh.pa.us        6677                 :          33609 :         opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
                               6678                 :                : 
                               6679                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6680                 :          33609 :         selectDumpableObject(&(opcinfo[i].dobj), fout);
                               6681                 :                :     }
                               6682                 :                : 
 8490 tgl@sss.pgh.pa.us        6683                 :            189 :     PQclear(res);
                               6684                 :                : 
                               6685                 :            189 :     destroyPQExpBuffer(query);
                               6686                 :            189 : }
                               6687                 :                : 
                               6688                 :                : /*
                               6689                 :                :  * getOpfamilies:
                               6690                 :                :  *    get information about all opfamilies in the system catalogs
                               6691                 :                :  */
                               6692                 :                : void
  482 nathan@postgresql.or     6693                 :            189 : getOpfamilies(Archive *fout)
                               6694                 :                : {
                               6695                 :                :     PGresult   *res;
                               6696                 :                :     int         ntups;
                               6697                 :                :     int         i;
                               6698                 :                :     PQExpBuffer query;
                               6699                 :                :     OpfamilyInfo *opfinfo;
                               6700                 :                :     int         i_tableoid;
                               6701                 :                :     int         i_oid;
                               6702                 :                :     int         i_opfmethod;
                               6703                 :                :     int         i_opfname;
                               6704                 :                :     int         i_opfnamespace;
                               6705                 :                :     int         i_opfowner;
                               6706                 :                : 
 6852 tgl@sss.pgh.pa.us        6707                 :            189 :     query = createPQExpBuffer();
                               6708                 :                : 
                               6709                 :                :     /*
                               6710                 :                :      * find all opfamilies, including builtin opfamilies; we filter out
                               6711                 :                :      * system-defined opfamilies at dump-out time.
                               6712                 :                :      */
                               6713                 :                : 
   88 noah@leadboat.com        6714                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opfmethod, opfname, "
                               6715                 :                :                          "opfnamespace, "
                               6716                 :                :                          "opfowner "
                               6717                 :                :                          "FROM pg_opfamily");
                               6718                 :                : 
 5011 rhaas@postgresql.org     6719                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6720                 :                : 
 6852 tgl@sss.pgh.pa.us        6721                 :            189 :     ntups = PQntuples(res);
                               6722                 :                : 
 5085 bruce@momjian.us         6723                 :            189 :     opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
                               6724                 :                : 
 6852 tgl@sss.pgh.pa.us        6725                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               6726                 :            189 :     i_oid = PQfnumber(res, "oid");
                               6727                 :            189 :     i_opfname = PQfnumber(res, "opfname");
   88 noah@leadboat.com        6728                 :            189 :     i_opfmethod = PQfnumber(res, "opfmethod");
 6852 tgl@sss.pgh.pa.us        6729                 :            189 :     i_opfnamespace = PQfnumber(res, "opfnamespace");
 1396                          6730                 :            189 :     i_opfowner = PQfnumber(res, "opfowner");
                               6731                 :                : 
 6852                          6732         [ +  + ]:          27922 :     for (i = 0; i < ntups; i++)
                               6733                 :                :     {
                               6734                 :          27733 :         opfinfo[i].dobj.objType = DO_OPFAMILY;
                               6735                 :          27733 :         opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6736                 :          27733 :         opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6737                 :          27733 :         AssignDumpId(&opfinfo[i].dobj);
 5085 bruce@momjian.us         6738                 :          27733 :         opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
 5012 rhaas@postgresql.org     6739                 :          55466 :         opfinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     6740                 :          27733 :             findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
   88 noah@leadboat.com        6741                 :          27733 :         opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
 1396 tgl@sss.pgh.pa.us        6742                 :          27733 :         opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
                               6743                 :                : 
                               6744                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6745                 :          27733 :         selectDumpableObject(&(opfinfo[i].dobj), fout);
                               6746                 :                :     }
                               6747                 :                : 
 6852 tgl@sss.pgh.pa.us        6748                 :            189 :     PQclear(res);
                               6749                 :                : 
                               6750                 :            189 :     destroyPQExpBuffer(query);
                               6751                 :            189 : }
                               6752                 :                : 
                               6753                 :                : /*
                               6754                 :                :  * getAggregates:
                               6755                 :                :  *    get information about all user-defined aggregates in the system catalogs
                               6756                 :                :  */
                               6757                 :                : void
  482 nathan@postgresql.or     6758                 :            189 : getAggregates(Archive *fout)
                               6759                 :                : {
 3575 tgl@sss.pgh.pa.us        6760                 :            189 :     DumpOptions *dopt = fout->dopt;
                               6761                 :                :     PGresult   *res;
                               6762                 :                :     int         ntups;
                               6763                 :                :     int         i;
 9329 bruce@momjian.us         6764                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               6765                 :                :     AggInfo    *agginfo;
                               6766                 :                :     int         i_tableoid;
                               6767                 :                :     int         i_oid;
                               6768                 :                :     int         i_aggname;
                               6769                 :                :     int         i_aggnamespace;
                               6770                 :                :     int         i_pronargs;
                               6771                 :                :     int         i_proargtypes;
                               6772                 :                :     int         i_proowner;
                               6773                 :                :     int         i_aggacl;
                               6774                 :                :     int         i_acldefault;
                               6775                 :                : 
                               6776                 :                :     /*
                               6777                 :                :      * Find all interesting aggregates.  See comment in getFuncs() for the
                               6778                 :                :      * rationale behind the filtering logic.
                               6779                 :                :      */
 3491 sfrost@snowman.net       6780         [ +  - ]:            189 :     if (fout->remoteVersion >= 90600)
                               6781                 :                :     {
                               6782                 :                :         const char *agg_check;
                               6783                 :                : 
 2796 peter_e@gmx.net          6784                 :            378 :         agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
                               6785         [ +  - ]:            189 :                      : "p.proisagg");
                               6786                 :                : 
 3491 sfrost@snowman.net       6787                 :            189 :         appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
                               6788                 :                :                           "p.proname AS aggname, "
                               6789                 :                :                           "p.pronamespace AS aggnamespace, "
                               6790                 :                :                           "p.pronargs, p.proargtypes, "
                               6791                 :                :                           "p.proowner, "
                               6792                 :                :                           "p.proacl AS aggacl, "
                               6793                 :                :                           "acldefault('f', p.proowner) AS acldefault "
                               6794                 :                :                           "FROM pg_proc p "
                               6795                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6796                 :                :                           "(p.oid = pip.objoid "
                               6797                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6798                 :                :                           "AND pip.objsubid = 0) "
                               6799                 :                :                           "WHERE %s AND ("
                               6800                 :                :                           "p.pronamespace != "
                               6801                 :                :                           "(SELECT oid FROM pg_namespace "
                               6802                 :                :                           "WHERE nspname = 'pg_catalog') OR "
                               6803                 :                :                           "p.proacl IS DISTINCT FROM pip.initprivs",
                               6804                 :                :                           agg_check);
                               6805         [ +  + ]:            189 :         if (dopt->binary_upgrade)
                               6806                 :             36 :             appendPQExpBufferStr(query,
                               6807                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6808                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6809                 :                :                                  "objid = p.oid AND "
                               6810                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6811                 :                :                                  "deptype = 'e')");
                               6812                 :            189 :         appendPQExpBufferChar(query, ')');
                               6813                 :                :     }
                               6814                 :                :     else
                               6815                 :                :     {
 1147 drowley@postgresql.o     6816                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
                               6817                 :                :                              "pronamespace AS aggnamespace, "
                               6818                 :                :                              "pronargs, proargtypes, "
                               6819                 :                :                              "proowner, "
                               6820                 :                :                              "proacl AS aggacl, "
                               6821                 :                :                              "acldefault('f', proowner) AS acldefault "
                               6822                 :                :                              "FROM pg_proc p "
                               6823                 :                :                              "WHERE proisagg AND ("
                               6824                 :                :                              "pronamespace != "
                               6825                 :                :                              "(SELECT oid FROM pg_namespace "
                               6826                 :                :                              "WHERE nspname = 'pg_catalog')");
 1421 tgl@sss.pgh.pa.us        6827         [ #  # ]:              0 :         if (dopt->binary_upgrade)
                               6828                 :              0 :             appendPQExpBufferStr(query,
                               6829                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6830                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6831                 :                :                                  "objid = p.oid AND "
                               6832                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6833                 :                :                                  "deptype = 'e')");
                               6834                 :              0 :         appendPQExpBufferChar(query, ')');
                               6835                 :                :     }
                               6836                 :                : 
 5011 rhaas@postgresql.org     6837                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6838                 :                : 
10277 bruce@momjian.us         6839                 :            189 :     ntups = PQntuples(res);
                               6840                 :                : 
 5085                          6841                 :            189 :     agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
                               6842                 :                : 
 7996 tgl@sss.pgh.pa.us        6843                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 8571                          6844                 :            189 :     i_oid = PQfnumber(res, "oid");
                               6845                 :            189 :     i_aggname = PQfnumber(res, "aggname");
                               6846                 :            189 :     i_aggnamespace = PQfnumber(res, "aggnamespace");
 7032                          6847                 :            189 :     i_pronargs = PQfnumber(res, "pronargs");
                               6848                 :            189 :     i_proargtypes = PQfnumber(res, "proargtypes");
 1396                          6849                 :            189 :     i_proowner = PQfnumber(res, "proowner");
 8562 peter_e@gmx.net          6850                 :            189 :     i_aggacl = PQfnumber(res, "aggacl");
 1421 tgl@sss.pgh.pa.us        6851                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
                               6852                 :                : 
10277 bruce@momjian.us         6853         [ +  + ]:            588 :     for (i = 0; i < ntups; i++)
                               6854                 :                :     {
 7996 tgl@sss.pgh.pa.us        6855                 :            399 :         agginfo[i].aggfn.dobj.objType = DO_AGG;
                               6856                 :            399 :         agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6857                 :            399 :         agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6858                 :            399 :         AssignDumpId(&agginfo[i].aggfn.dobj);
 5085 bruce@momjian.us         6859                 :            399 :         agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
 5012 rhaas@postgresql.org     6860                 :            798 :         agginfo[i].aggfn.dobj.namespace =
 1889 peter@eisentraut.org     6861                 :            399 :             findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
 1421 tgl@sss.pgh.pa.us        6862                 :            399 :         agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
                               6863                 :            399 :         agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6864                 :            399 :         agginfo[i].aggfn.dacl.privtype = 0;
                               6865                 :            399 :         agginfo[i].aggfn.dacl.initprivs = NULL;
 1396                          6866                 :            399 :         agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 3050                          6867                 :            399 :         agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
                               6868                 :            399 :         agginfo[i].aggfn.prorettype = InvalidOid;   /* not saved */
 7032                          6869                 :            399 :         agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               6870         [ +  + ]:            399 :         if (agginfo[i].aggfn.nargs == 0)
                               6871                 :             56 :             agginfo[i].aggfn.argtypes = NULL;
                               6872                 :                :         else
                               6873                 :                :         {
 5085 bruce@momjian.us         6874                 :            343 :             agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
 3302 tgl@sss.pgh.pa.us        6875                 :            343 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               6876                 :            343 :                           agginfo[i].aggfn.argtypes,
                               6877                 :            343 :                           agginfo[i].aggfn.nargs);
                               6878                 :                :         }
  876                          6879                 :            399 :         agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
                               6880                 :                : 
                               6881                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       6882                 :            399 :         selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
                               6883                 :                : 
                               6884                 :                :         /* Mark whether aggregate has an ACL */
 1421 tgl@sss.pgh.pa.us        6885         [ +  + ]:            399 :         if (!PQgetisnull(res, i, i_aggacl))
                               6886                 :             25 :             agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
                               6887                 :                :     }
                               6888                 :                : 
 8571                          6889                 :            189 :     PQclear(res);
                               6890                 :                : 
                               6891                 :            189 :     destroyPQExpBuffer(query);
                               6892                 :            189 : }
                               6893                 :                : 
                               6894                 :                : /*
                               6895                 :                :  * getFuncs:
                               6896                 :                :  *    get information about all user-defined functions in the system catalogs
                               6897                 :                :  */
                               6898                 :                : void
  482 nathan@postgresql.or     6899                 :            189 : getFuncs(Archive *fout)
                               6900                 :                : {
 3575 tgl@sss.pgh.pa.us        6901                 :            189 :     DumpOptions *dopt = fout->dopt;
                               6902                 :                :     PGresult   *res;
                               6903                 :                :     int         ntups;
                               6904                 :                :     int         i;
 8571                          6905                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               6906                 :                :     FuncInfo   *finfo;
                               6907                 :                :     int         i_tableoid;
                               6908                 :                :     int         i_oid;
                               6909                 :                :     int         i_proname;
                               6910                 :                :     int         i_pronamespace;
                               6911                 :                :     int         i_proowner;
                               6912                 :                :     int         i_prolang;
                               6913                 :                :     int         i_pronargs;
                               6914                 :                :     int         i_proargtypes;
                               6915                 :                :     int         i_prorettype;
                               6916                 :                :     int         i_proacl;
                               6917                 :                :     int         i_acldefault;
                               6918                 :                : 
                               6919                 :                :     /*
                               6920                 :                :      * Find all interesting functions.  This is a bit complicated:
                               6921                 :                :      *
                               6922                 :                :      * 1. Always exclude aggregates; those are handled elsewhere.
                               6923                 :                :      *
                               6924                 :                :      * 2. Always exclude functions that are internally dependent on something
                               6925                 :                :      * else, since presumably those will be created as a result of creating
                               6926                 :                :      * the something else.  This currently acts only to suppress constructor
                               6927                 :                :      * functions for range types.  Note this is OK only because the
                               6928                 :                :      * constructors don't have any dependencies the range type doesn't have;
                               6929                 :                :      * otherwise we might not get creation ordering correct.
                               6930                 :                :      *
                               6931                 :                :      * 3. Otherwise, we normally exclude functions in pg_catalog.  However, if
                               6932                 :                :      * they're members of extensions and we are in binary-upgrade mode then
                               6933                 :                :      * include them, since we want to dump extension members individually in
                               6934                 :                :      * that mode.  Also, if they are used by casts or transforms then we need
                               6935                 :                :      * to gather the information about them, though they won't be dumped if
                               6936                 :                :      * they are built-in.  Also, in 9.6 and up, include functions in
                               6937                 :                :      * pg_catalog if they have an ACL different from what's shown in
                               6938                 :                :      * pg_init_privs (so we have to join to pg_init_privs; annoying).
                               6939                 :                :      */
 3491 sfrost@snowman.net       6940         [ +  - ]:            189 :     if (fout->remoteVersion >= 90600)
                               6941                 :                :     {
                               6942                 :                :         const char *not_agg_check;
                               6943                 :                : 
 2796 peter_e@gmx.net          6944                 :            378 :         not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
                               6945         [ +  - ]:            189 :                          : "NOT p.proisagg");
                               6946                 :                : 
 3491 sfrost@snowman.net       6947                 :            189 :         appendPQExpBuffer(query,
                               6948                 :                :                           "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
                               6949                 :                :                           "p.pronargs, p.proargtypes, p.prorettype, "
                               6950                 :                :                           "p.proacl, "
                               6951                 :                :                           "acldefault('f', p.proowner) AS acldefault, "
                               6952                 :                :                           "p.pronamespace, "
                               6953                 :                :                           "p.proowner "
                               6954                 :                :                           "FROM pg_proc p "
                               6955                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6956                 :                :                           "(p.oid = pip.objoid "
                               6957                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6958                 :                :                           "AND pip.objsubid = 0) "
                               6959                 :                :                           "WHERE %s"
                               6960                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6961                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               6962                 :                :                           "objid = p.oid AND deptype = 'i')"
                               6963                 :                :                           "\n  AND ("
                               6964                 :                :                           "\n  pronamespace != "
                               6965                 :                :                           "(SELECT oid FROM pg_namespace "
                               6966                 :                :                           "WHERE nspname = 'pg_catalog')"
                               6967                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               6968                 :                :                           "\n  WHERE pg_cast.oid > %u "
                               6969                 :                :                           "\n  AND p.oid = pg_cast.castfunc)"
                               6970                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               6971                 :                :                           "\n  WHERE pg_transform.oid > %u AND "
                               6972                 :                :                           "\n  (p.oid = pg_transform.trffromsql"
                               6973                 :                :                           "\n  OR p.oid = pg_transform.trftosql))",
                               6974                 :                :                           not_agg_check,
                               6975                 :                :                           g_last_builtin_oid,
                               6976                 :                :                           g_last_builtin_oid);
                               6977         [ +  + ]:            189 :         if (dopt->binary_upgrade)
                               6978                 :             36 :             appendPQExpBufferStr(query,
                               6979                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6980                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6981                 :                :                                  "objid = p.oid AND "
                               6982                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6983                 :                :                                  "deptype = 'e')");
 3321 tgl@sss.pgh.pa.us        6984                 :            189 :         appendPQExpBufferStr(query,
                               6985                 :                :                              "\n  OR p.proacl IS DISTINCT FROM pip.initprivs");
 3491 sfrost@snowman.net       6986                 :            189 :         appendPQExpBufferChar(query, ')');
                               6987                 :                :     }
                               6988                 :                :     else
                               6989                 :                :     {
 8571 tgl@sss.pgh.pa.us        6990                 :UBC           0 :         appendPQExpBuffer(query,
                               6991                 :                :                           "SELECT tableoid, oid, proname, prolang, "
                               6992                 :                :                           "pronargs, proargtypes, prorettype, proacl, "
                               6993                 :                :                           "acldefault('f', proowner) AS acldefault, "
                               6994                 :                :                           "pronamespace, "
                               6995                 :                :                           "proowner "
                               6996                 :                :                           "FROM pg_proc p "
                               6997                 :                :                           "WHERE NOT proisagg"
                               6998                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6999                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               7000                 :                :                           "objid = p.oid AND deptype = 'i')"
                               7001                 :                :                           "\n  AND ("
                               7002                 :                :                           "\n  pronamespace != "
                               7003                 :                :                           "(SELECT oid FROM pg_namespace "
                               7004                 :                :                           "WHERE nspname = 'pg_catalog')"
                               7005                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               7006                 :                :                           "\n  WHERE pg_cast.oid > '%u'::oid"
                               7007                 :                :                           "\n  AND p.oid = pg_cast.castfunc)",
                               7008                 :                :                           g_last_builtin_oid);
                               7009                 :                : 
 3232 sfrost@snowman.net       7010         [ #  # ]:              0 :         if (fout->remoteVersion >= 90500)
                               7011                 :              0 :             appendPQExpBuffer(query,
                               7012                 :                :                               "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               7013                 :                :                               "\n  WHERE pg_transform.oid > '%u'::oid"
                               7014                 :                :                               "\n  AND (p.oid = pg_transform.trffromsql"
                               7015                 :                :                               "\n  OR p.oid = pg_transform.trftosql))",
                               7016                 :                :                               g_last_builtin_oid);
                               7017                 :                : 
 1413 tgl@sss.pgh.pa.us        7018         [ #  # ]:              0 :         if (dopt->binary_upgrade)
 4361 heikki.linnakangas@i     7019                 :              0 :             appendPQExpBufferStr(query,
                               7020                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               7021                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               7022                 :                :                                  "objid = p.oid AND "
                               7023                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               7024                 :                :                                  "deptype = 'e')");
                               7025                 :              0 :         appendPQExpBufferChar(query, ')');
                               7026                 :                :     }
                               7027                 :                : 
 5011 rhaas@postgresql.org     7028                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7029                 :                : 
 8571 tgl@sss.pgh.pa.us        7030                 :            189 :     ntups = PQntuples(res);
                               7031                 :                : 
 4773                          7032                 :            189 :     finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
                               7033                 :                : 
 7996                          7034                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 8571                          7035                 :            189 :     i_oid = PQfnumber(res, "oid");
                               7036                 :            189 :     i_proname = PQfnumber(res, "proname");
                               7037                 :            189 :     i_pronamespace = PQfnumber(res, "pronamespace");
 1396                          7038                 :            189 :     i_proowner = PQfnumber(res, "proowner");
 8571                          7039                 :            189 :     i_prolang = PQfnumber(res, "prolang");
                               7040                 :            189 :     i_pronargs = PQfnumber(res, "pronargs");
                               7041                 :            189 :     i_proargtypes = PQfnumber(res, "proargtypes");
                               7042                 :            189 :     i_prorettype = PQfnumber(res, "prorettype");
 8562 peter_e@gmx.net          7043                 :            189 :     i_proacl = PQfnumber(res, "proacl");
 1421 tgl@sss.pgh.pa.us        7044                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
                               7045                 :                : 
 8571                          7046         [ +  + ]:           4970 :     for (i = 0; i < ntups; i++)
                               7047                 :                :     {
 7996                          7048                 :           4781 :         finfo[i].dobj.objType = DO_FUNC;
                               7049                 :           4781 :         finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               7050                 :           4781 :         finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               7051                 :           4781 :         AssignDumpId(&finfo[i].dobj);
 5085 bruce@momjian.us         7052                 :           4781 :         finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
 7317                          7053                 :           9562 :         finfo[i].dobj.namespace =
 1889 peter@eisentraut.org     7054                 :           4781 :             findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
 1421 tgl@sss.pgh.pa.us        7055                 :           4781 :         finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
                               7056                 :           4781 :         finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               7057                 :           4781 :         finfo[i].dacl.privtype = 0;
                               7058                 :           4781 :         finfo[i].dacl.initprivs = NULL;
 1396                          7059                 :           4781 :         finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 8571                          7060                 :           4781 :         finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
 7996                          7061                 :           4781 :         finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
 8571                          7062                 :           4781 :         finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               7063         [ +  + ]:           4781 :         if (finfo[i].nargs == 0)
                               7064                 :           1063 :             finfo[i].argtypes = NULL;
                               7065                 :                :         else
                               7066                 :                :         {
 5085 bruce@momjian.us         7067                 :           3718 :             finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
 7996 tgl@sss.pgh.pa.us        7068                 :           3718 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               7069                 :           3718 :                           finfo[i].argtypes, finfo[i].nargs);
                               7070                 :                :         }
  876                          7071                 :           4781 :         finfo[i].postponed_def = false; /* might get set during sort */
                               7072                 :                : 
                               7073                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       7074                 :           4781 :         selectDumpableObject(&(finfo[i].dobj), fout);
                               7075                 :                : 
                               7076                 :                :         /* Mark whether function has an ACL */
 1421 tgl@sss.pgh.pa.us        7077         [ +  + ]:           4781 :         if (!PQgetisnull(res, i, i_proacl))
                               7078                 :            140 :             finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               7079                 :                :     }
                               7080                 :                : 
 8571                          7081                 :            189 :     PQclear(res);
                               7082                 :                : 
                               7083                 :            189 :     destroyPQExpBuffer(query);
                               7084                 :            189 : }
                               7085                 :                : 
                               7086                 :                : /*
                               7087                 :                :  * getRelationStatistics
                               7088                 :                :  *    register the statistics object as a dependent of the relation.
                               7089                 :                :  *
                               7090                 :                :  * reltuples is passed as a string to avoid complexities in converting from/to
                               7091                 :                :  * floating point.
                               7092                 :                :  */
                               7093                 :                : static RelStatsInfo *
  244 jdavis@postgresql.or     7094                 :           9554 : getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
                               7095                 :                :                       char *reltuples, int32 relallvisible,
                               7096                 :                :                       int32 relallfrozen, char relkind,
                               7097                 :                :                       char **indAttNames, int nindAttNames)
                               7098                 :                : {
  249                          7099         [ +  + ]:           9554 :     if (!fout->dopt->dumpStatistics)
                               7100                 :           6022 :         return NULL;
                               7101                 :                : 
                               7102   [ +  +  +  + ]:           3532 :     if ((relkind == RELKIND_RELATION) ||
                               7103         [ +  + ]:           1481 :         (relkind == RELKIND_PARTITIONED_TABLE) ||
                               7104         [ +  + ]:            887 :         (relkind == RELKIND_INDEX) ||
                               7105         [ +  + ]:            575 :         (relkind == RELKIND_PARTITIONED_INDEX) ||
  131 fujii@postgresql.org     7106         [ +  + ]:            269 :         (relkind == RELKIND_MATVIEW ||
                               7107                 :                :          relkind == RELKIND_FOREIGN_TABLE))
                               7108                 :                :     {
  249 jdavis@postgresql.or     7109                 :           3295 :         RelStatsInfo *info = pg_malloc0(sizeof(RelStatsInfo));
                               7110                 :           3295 :         DumpableObject *dobj = &info->dobj;
                               7111                 :                : 
                               7112                 :           3295 :         dobj->objType = DO_REL_STATS;
                               7113                 :           3295 :         dobj->catId.tableoid = 0;
                               7114                 :           3295 :         dobj->catId.oid = 0;
                               7115                 :           3295 :         AssignDumpId(dobj);
                               7116                 :           3295 :         dobj->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               7117                 :           3295 :         dobj->dependencies[0] = rel->dumpId;
                               7118                 :           3295 :         dobj->nDeps = 1;
                               7119                 :           3295 :         dobj->allocDeps = 1;
                               7120                 :           3295 :         dobj->components |= DUMP_COMPONENT_STATISTICS;
                               7121                 :           3295 :         dobj->name = pg_strdup(rel->name);
                               7122                 :           3295 :         dobj->namespace = rel->namespace;
  244                          7123                 :           3295 :         info->relpages = relpages;
  233                          7124                 :           3295 :         info->reltuples = pstrdup(reltuples);
  244                          7125                 :           3295 :         info->relallvisible = relallvisible;
  211                          7126                 :           3295 :         info->relallfrozen = relallfrozen;
  249                          7127                 :           3295 :         info->relkind = relkind;
  243 tgl@sss.pgh.pa.us        7128                 :           3295 :         info->indAttNames = indAttNames;
                               7129                 :           3295 :         info->nindAttNames = nindAttNames;
                               7130                 :                : 
                               7131                 :                :         /*
                               7132                 :                :          * Ordinarily, stats go in SECTION_DATA for tables and
                               7133                 :                :          * SECTION_POST_DATA for indexes.
                               7134                 :                :          *
                               7135                 :                :          * However, the section may be updated later for materialized view
                               7136                 :                :          * stats. REFRESH MATERIALIZED VIEW replaces the storage and resets
                               7137                 :                :          * the stats, so the stats must be restored after the data. Also, the
                               7138                 :                :          * materialized view definition may be postponed to SECTION_POST_DATA
                               7139                 :                :          * (see repairMatViewBoundaryMultiLoop()).
                               7140                 :                :          */
  213 jdavis@postgresql.or     7141      [ +  +  - ]:           3295 :         switch (info->relkind)
                               7142                 :                :         {
                               7143                 :           2389 :             case RELKIND_RELATION:
                               7144                 :                :             case RELKIND_PARTITIONED_TABLE:
                               7145                 :                :             case RELKIND_MATVIEW:
                               7146                 :                :             case RELKIND_FOREIGN_TABLE:
                               7147                 :           2389 :                 info->section = SECTION_DATA;
                               7148                 :           2389 :                 break;
                               7149                 :            906 :             case RELKIND_INDEX:
                               7150                 :                :             case RELKIND_PARTITIONED_INDEX:
                               7151                 :            906 :                 info->section = SECTION_POST_DATA;
                               7152                 :            906 :                 break;
  213 jdavis@postgresql.or     7153                 :UBC           0 :             default:
  133 peter@eisentraut.org     7154                 :              0 :                 pg_fatal("cannot dump statistics for relation kind \"%c\"",
                               7155                 :                :                          info->relkind);
                               7156                 :                :         }
                               7157                 :                : 
  249 jdavis@postgresql.or     7158                 :CBC        3295 :         return info;
                               7159                 :                :     }
                               7160                 :            237 :     return NULL;
                               7161                 :                : }
                               7162                 :                : 
                               7163                 :                : /*
                               7164                 :                :  * getTables
                               7165                 :                :  *    read all the tables (no indexes) in the system catalogs,
                               7166                 :                :  *    and return them as an array of TableInfo structures
                               7167                 :                :  *
                               7168                 :                :  * *numTables is set to the number of tables read in
                               7169                 :                :  */
                               7170                 :                : TableInfo *
 3575 tgl@sss.pgh.pa.us        7171                 :            190 : getTables(Archive *fout, int *numTables)
                               7172                 :                : {
                               7173                 :            190 :     DumpOptions *dopt = fout->dopt;
                               7174                 :                :     PGresult   *res;
                               7175                 :                :     int         ntups;
                               7176                 :                :     int         i;
 8571                          7177                 :            190 :     PQExpBuffer query = createPQExpBuffer();
                               7178                 :                :     TableInfo  *tblinfo;
                               7179                 :                :     int         i_reltableoid;
                               7180                 :                :     int         i_reloid;
                               7181                 :                :     int         i_relname;
                               7182                 :                :     int         i_relnamespace;
                               7183                 :                :     int         i_relkind;
                               7184                 :                :     int         i_reltype;
                               7185                 :                :     int         i_relowner;
                               7186                 :                :     int         i_relchecks;
                               7187                 :                :     int         i_relhasindex;
                               7188                 :                :     int         i_relhasrules;
                               7189                 :                :     int         i_relpages;
                               7190                 :                :     int         i_reltuples;
                               7191                 :                :     int         i_relallvisible;
                               7192                 :                :     int         i_relallfrozen;
                               7193                 :                :     int         i_toastpages;
                               7194                 :                :     int         i_owning_tab;
                               7195                 :                :     int         i_owning_col;
                               7196                 :                :     int         i_reltablespace;
                               7197                 :                :     int         i_relhasoids;
                               7198                 :                :     int         i_relhastriggers;
                               7199                 :                :     int         i_relpersistence;
                               7200                 :                :     int         i_relispopulated;
                               7201                 :                :     int         i_relreplident;
                               7202                 :                :     int         i_relrowsec;
                               7203                 :                :     int         i_relforcerowsec;
                               7204                 :                :     int         i_relfrozenxid;
                               7205                 :                :     int         i_toastfrozenxid;
                               7206                 :                :     int         i_toastoid;
                               7207                 :                :     int         i_relminmxid;
                               7208                 :                :     int         i_toastminmxid;
                               7209                 :                :     int         i_reloptions;
                               7210                 :                :     int         i_checkoption;
                               7211                 :                :     int         i_toastreloptions;
                               7212                 :                :     int         i_reloftype;
                               7213                 :                :     int         i_foreignserver;
                               7214                 :                :     int         i_amname;
                               7215                 :                :     int         i_is_identity_sequence;
                               7216                 :                :     int         i_relacl;
                               7217                 :                :     int         i_acldefault;
                               7218                 :                :     int         i_ispartition;
                               7219                 :                : 
                               7220                 :                :     /*
                               7221                 :                :      * Find all the tables and table-like objects.
                               7222                 :                :      *
                               7223                 :                :      * We must fetch all tables in this phase because otherwise we cannot
                               7224                 :                :      * correctly identify inherited columns, owned sequences, etc.
                               7225                 :                :      *
                               7226                 :                :      * We include system catalogs, so that we can work if a user table is
                               7227                 :                :      * defined to inherit from a system catalog (pretty weird, but...)
                               7228                 :                :      *
                               7229                 :                :      * Note: in this phase we should collect only a minimal amount of
                               7230                 :                :      * information about each table, basically just enough to decide if it is
                               7231                 :                :      * interesting.  In particular, since we do not yet have lock on any user
                               7232                 :                :      * table, we MUST NOT invoke any server-side data collection functions
                               7233                 :                :      * (for instance, pg_get_partkeydef()).  Those are likely to fail or give
                               7234                 :                :      * wrong answers if any concurrent DDL is happening.
                               7235                 :                :      */
                               7236                 :                : 
 1147 drowley@postgresql.o     7237                 :            190 :     appendPQExpBufferStr(query,
                               7238                 :                :                          "SELECT c.tableoid, c.oid, c.relname, "
                               7239                 :                :                          "c.relnamespace, c.relkind, c.reltype, "
                               7240                 :                :                          "c.relowner, "
                               7241                 :                :                          "c.relchecks, "
                               7242                 :                :                          "c.relhasindex, c.relhasrules, c.relpages, "
                               7243                 :                :                          "c.reltuples, c.relallvisible, ");
                               7244                 :                : 
  211 jdavis@postgresql.or     7245         [ +  - ]:            190 :     if (fout->remoteVersion >= 180000)
                               7246                 :            190 :         appendPQExpBufferStr(query, "c.relallfrozen, ");
                               7247                 :                :     else
  211 jdavis@postgresql.or     7248                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS relallfrozen, ");
                               7249                 :                : 
  211 jdavis@postgresql.or     7250                 :CBC         190 :     appendPQExpBufferStr(query,
                               7251                 :                :                          "c.relhastriggers, c.relpersistence, "
                               7252                 :                :                          "c.reloftype, "
                               7253                 :                :                          "c.relacl, "
                               7254                 :                :                          "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
                               7255                 :                :                          " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
                               7256                 :                :                          "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
                               7257                 :                :                          "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
                               7258                 :                :                          "ELSE 0 END AS foreignserver, "
                               7259                 :                :                          "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
                               7260                 :                :                          "tc.oid AS toid, "
                               7261                 :                :                          "tc.relpages AS toastpages, "
                               7262                 :                :                          "tc.reloptions AS toast_reloptions, "
                               7263                 :                :                          "d.refobjid AS owning_tab, "
                               7264                 :                :                          "d.refobjsubid AS owning_col, "
                               7265                 :                :                          "tsp.spcname AS reltablespace, ");
                               7266                 :                : 
 1469 tgl@sss.pgh.pa.us        7267         [ +  - ]:            190 :     if (fout->remoteVersion >= 120000)
                               7268                 :            190 :         appendPQExpBufferStr(query,
                               7269                 :                :                              "false AS relhasoids, ");
                               7270                 :                :     else
 1469 tgl@sss.pgh.pa.us        7271                 :UBC           0 :         appendPQExpBufferStr(query,
                               7272                 :                :                              "c.relhasoids, ");
                               7273                 :                : 
 1469 tgl@sss.pgh.pa.us        7274         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90300)
                               7275                 :            190 :         appendPQExpBufferStr(query,
                               7276                 :                :                              "c.relispopulated, ");
                               7277                 :                :     else
 1469 tgl@sss.pgh.pa.us        7278                 :UBC           0 :         appendPQExpBufferStr(query,
                               7279                 :                :                              "'t' as relispopulated, ");
                               7280                 :                : 
 1469 tgl@sss.pgh.pa.us        7281         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90400)
                               7282                 :            190 :         appendPQExpBufferStr(query,
                               7283                 :                :                              "c.relreplident, ");
                               7284                 :                :     else
 1469 tgl@sss.pgh.pa.us        7285                 :UBC           0 :         appendPQExpBufferStr(query,
                               7286                 :                :                              "'d' AS relreplident, ");
                               7287                 :                : 
 1469 tgl@sss.pgh.pa.us        7288         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90500)
                               7289                 :            190 :         appendPQExpBufferStr(query,
                               7290                 :                :                              "c.relrowsecurity, c.relforcerowsecurity, ");
                               7291                 :                :     else
 1469 tgl@sss.pgh.pa.us        7292                 :UBC           0 :         appendPQExpBufferStr(query,
                               7293                 :                :                              "false AS relrowsecurity, "
                               7294                 :                :                              "false AS relforcerowsecurity, ");
                               7295                 :                : 
 1469 tgl@sss.pgh.pa.us        7296         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90300)
                               7297                 :            190 :         appendPQExpBufferStr(query,
                               7298                 :                :                              "c.relminmxid, tc.relminmxid AS tminmxid, ");
                               7299                 :                :     else
 1469 tgl@sss.pgh.pa.us        7300                 :UBC           0 :         appendPQExpBufferStr(query,
                               7301                 :                :                              "0 AS relminmxid, 0 AS tminmxid, ");
                               7302                 :                : 
 1469 tgl@sss.pgh.pa.us        7303         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90300)
                               7304                 :            190 :         appendPQExpBufferStr(query,
                               7305                 :                :                              "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
                               7306                 :                :                              "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
                               7307                 :                :                              "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
                               7308                 :                :     else
 1469 tgl@sss.pgh.pa.us        7309                 :UBC           0 :         appendPQExpBufferStr(query,
                               7310                 :                :                              "c.reloptions, NULL AS checkoption, ");
                               7311                 :                : 
 3491 sfrost@snowman.net       7312         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90600)
 1469 tgl@sss.pgh.pa.us        7313                 :            190 :         appendPQExpBufferStr(query,
                               7314                 :                :                              "am.amname, ");
                               7315                 :                :     else
 1469 tgl@sss.pgh.pa.us        7316                 :UBC           0 :         appendPQExpBufferStr(query,
                               7317                 :                :                              "NULL AS amname, ");
                               7318                 :                : 
 1469 tgl@sss.pgh.pa.us        7319         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 90600)
                               7320                 :            190 :         appendPQExpBufferStr(query,
                               7321                 :                :                              "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
                               7322                 :                :     else
 1469 tgl@sss.pgh.pa.us        7323                 :UBC           0 :         appendPQExpBufferStr(query,
                               7324                 :                :                              "false AS is_identity_sequence, ");
                               7325                 :                : 
 1469 tgl@sss.pgh.pa.us        7326         [ +  - ]:CBC         190 :     if (fout->remoteVersion >= 100000)
                               7327                 :            190 :         appendPQExpBufferStr(query,
                               7328                 :                :                              "c.relispartition AS ispartition ");
                               7329                 :                :     else
 1469 tgl@sss.pgh.pa.us        7330                 :UBC           0 :         appendPQExpBufferStr(query,
                               7331                 :                :                              "false AS ispartition ");
                               7332                 :                : 
                               7333                 :                :     /*
                               7334                 :                :      * Left join to pg_depend to pick up dependency info linking sequences to
                               7335                 :                :      * their owning column, if any (note this dependency is AUTO except for
                               7336                 :                :      * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
                               7337                 :                :      * collect the spcname.
                               7338                 :                :      */
 1469 tgl@sss.pgh.pa.us        7339                 :CBC         190 :     appendPQExpBufferStr(query,
                               7340                 :                :                          "\nFROM pg_class c\n"
                               7341                 :                :                          "LEFT JOIN pg_depend d ON "
                               7342                 :                :                          "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
                               7343                 :                :                          "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
                               7344                 :                :                          "d.objsubid = 0 AND "
                               7345                 :                :                          "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
                               7346                 :                :                          "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
                               7347                 :                : 
                               7348                 :                :     /*
                               7349                 :                :      * In 9.6 and up, left join to pg_am to pick up the amname.
                               7350                 :                :      */
                               7351         [ +  - ]:            190 :     if (fout->remoteVersion >= 90600)
                               7352                 :            190 :         appendPQExpBufferStr(query,
                               7353                 :                :                              "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
                               7354                 :                : 
                               7355                 :                :     /*
                               7356                 :                :      * We purposefully ignore toast OIDs for partitioned tables; the reason is
                               7357                 :                :      * that versions 10 and 11 have them, but later versions do not, so
                               7358                 :                :      * emitting them causes the upgrade to fail.
                               7359                 :                :      */
 1421                          7360                 :            190 :     appendPQExpBufferStr(query,
                               7361                 :                :                          "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
                               7362                 :                :                          " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
                               7363                 :                :                          " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
                               7364                 :                : 
                               7365                 :                :     /*
                               7366                 :                :      * Restrict to interesting relkinds (in particular, not indexes).  Not all
                               7367                 :                :      * relkinds are possible in older servers, but it's not worth the trouble
                               7368                 :                :      * to emit a version-dependent list.
                               7369                 :                :      *
                               7370                 :                :      * Composite-type table entries won't be dumped as such, but we have to
                               7371                 :                :      * make a DumpableObject for them so that we can track dependencies of the
                               7372                 :                :      * composite type (pg_depend entries for columns of the composite type
                               7373                 :                :      * link to the pg_class entry not the pg_type entry).
                               7374                 :                :      */
 1469                          7375                 :            190 :     appendPQExpBufferStr(query,
                               7376                 :                :                          "WHERE c.relkind IN ("
                               7377                 :                :                          CppAsString2(RELKIND_RELATION) ", "
                               7378                 :                :                          CppAsString2(RELKIND_SEQUENCE) ", "
                               7379                 :                :                          CppAsString2(RELKIND_VIEW) ", "
                               7380                 :                :                          CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
                               7381                 :                :                          CppAsString2(RELKIND_MATVIEW) ", "
                               7382                 :                :                          CppAsString2(RELKIND_FOREIGN_TABLE) ", "
                               7383                 :                :                          CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
                               7384                 :                :                          "ORDER BY c.oid");
                               7385                 :                : 
 5011 rhaas@postgresql.org     7386                 :            190 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7387                 :                : 
 8571 tgl@sss.pgh.pa.us        7388                 :            190 :     ntups = PQntuples(res);
                               7389                 :                : 
                               7390                 :            190 :     *numTables = ntups;
                               7391                 :                : 
                               7392                 :                :     /*
                               7393                 :                :      * Extract data from result and lock dumpable tables.  We do the locking
                               7394                 :                :      * before anything else, to minimize the window wherein a table could
                               7395                 :                :      * disappear under us.
                               7396                 :                :      *
                               7397                 :                :      * Note that we have to save info about all tables here, even when dumping
                               7398                 :                :      * only one, because we don't yet know which tables might be inheritance
                               7399                 :                :      * ancestors of the target table.
                               7400                 :                :      */
 4773                          7401                 :            190 :     tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
                               7402                 :                : 
 7996                          7403                 :            190 :     i_reltableoid = PQfnumber(res, "tableoid");
 8571                          7404                 :            190 :     i_reloid = PQfnumber(res, "oid");
                               7405                 :            190 :     i_relname = PQfnumber(res, "relname");
                               7406                 :            190 :     i_relnamespace = PQfnumber(res, "relnamespace");
                               7407                 :            190 :     i_relkind = PQfnumber(res, "relkind");
 1421                          7408                 :            190 :     i_reltype = PQfnumber(res, "reltype");
 1396                          7409                 :            190 :     i_relowner = PQfnumber(res, "relowner");
 8571                          7410                 :            190 :     i_relchecks = PQfnumber(res, "relchecks");
                               7411                 :            190 :     i_relhasindex = PQfnumber(res, "relhasindex");
                               7412                 :            190 :     i_relhasrules = PQfnumber(res, "relhasrules");
 1469                          7413                 :            190 :     i_relpages = PQfnumber(res, "relpages");
  244 jdavis@postgresql.or     7414                 :            190 :     i_reltuples = PQfnumber(res, "reltuples");
                               7415                 :            190 :     i_relallvisible = PQfnumber(res, "relallvisible");
  211                          7416                 :            190 :     i_relallfrozen = PQfnumber(res, "relallfrozen");
 1421 tgl@sss.pgh.pa.us        7417                 :            190 :     i_toastpages = PQfnumber(res, "toastpages");
 1469                          7418                 :            190 :     i_owning_tab = PQfnumber(res, "owning_tab");
                               7419                 :            190 :     i_owning_col = PQfnumber(res, "owning_col");
                               7420                 :            190 :     i_reltablespace = PQfnumber(res, "reltablespace");
                               7421                 :            190 :     i_relhasoids = PQfnumber(res, "relhasoids");
                               7422                 :            190 :     i_relhastriggers = PQfnumber(res, "relhastriggers");
                               7423                 :            190 :     i_relpersistence = PQfnumber(res, "relpersistence");
                               7424                 :            190 :     i_relispopulated = PQfnumber(res, "relispopulated");
                               7425                 :            190 :     i_relreplident = PQfnumber(res, "relreplident");
 4051 sfrost@snowman.net       7426                 :            190 :     i_relrowsec = PQfnumber(res, "relrowsecurity");
 3676                          7427                 :            190 :     i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
 6095 bruce@momjian.us         7428                 :            190 :     i_relfrozenxid = PQfnumber(res, "relfrozenxid");
 5316                          7429                 :            190 :     i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
 1469 tgl@sss.pgh.pa.us        7430                 :            190 :     i_toastoid = PQfnumber(res, "toid");
                               7431                 :            190 :     i_relminmxid = PQfnumber(res, "relminmxid");
 4135 bruce@momjian.us         7432                 :            190 :     i_toastminmxid = PQfnumber(res, "tminmxid");
 7057                          7433                 :            190 :     i_reloptions = PQfnumber(res, "reloptions");
 4484 sfrost@snowman.net       7434                 :            190 :     i_checkoption = PQfnumber(res, "checkoption");
 6111 alvherre@alvh.no-ip.     7435                 :            190 :     i_toastreloptions = PQfnumber(res, "toast_reloptions");
 5751 peter_e@gmx.net          7436                 :            190 :     i_reloftype = PQfnumber(res, "reloftype");
 1469 tgl@sss.pgh.pa.us        7437                 :            190 :     i_foreignserver = PQfnumber(res, "foreignserver");
                               7438                 :            190 :     i_amname = PQfnumber(res, "amname");
 3126 peter_e@gmx.net          7439                 :            190 :     i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
 1469 tgl@sss.pgh.pa.us        7440                 :            190 :     i_relacl = PQfnumber(res, "relacl");
 1421                          7441                 :            190 :     i_acldefault = PQfnumber(res, "acldefault");
 3098 sfrost@snowman.net       7442                 :            190 :     i_ispartition = PQfnumber(res, "ispartition");
                               7443                 :                : 
 3302 tgl@sss.pgh.pa.us        7444         [ +  + ]:            190 :     if (dopt->lockWaitTimeout)
                               7445                 :                :     {
                               7446                 :                :         /*
                               7447                 :                :          * Arrange to fail instead of waiting forever for a table lock.
                               7448                 :                :          *
                               7449                 :                :          * NB: this coding assumes that the only queries issued within the
                               7450                 :                :          * following loop are LOCK TABLEs; else the timeout may be undesirably
                               7451                 :                :          * applied to other things too.
                               7452                 :                :          */
 6308                          7453                 :              2 :         resetPQExpBuffer(query);
 4361 heikki.linnakangas@i     7454                 :              2 :         appendPQExpBufferStr(query, "SET statement_timeout = ");
 4031 alvherre@alvh.no-ip.     7455                 :              2 :         appendStringLiteralConn(query, dopt->lockWaitTimeout, GetConnection(fout));
 5011 rhaas@postgresql.org     7456                 :              2 :         ExecuteSqlStatement(fout, query->data);
                               7457                 :                :     }
                               7458                 :                : 
 1028 tgl@sss.pgh.pa.us        7459                 :            190 :     resetPQExpBuffer(query);
                               7460                 :                : 
 8571                          7461         [ +  + ]:          50102 :     for (i = 0; i < ntups; i++)
                               7462                 :                :     {
  244 jdavis@postgresql.or     7463                 :          49912 :         int32       relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
  211                          7464                 :          49912 :         int32       relallfrozen = atoi(PQgetvalue(res, i, i_relallfrozen));
                               7465                 :                : 
 7996 tgl@sss.pgh.pa.us        7466                 :          49912 :         tblinfo[i].dobj.objType = DO_TABLE;
                               7467                 :          49912 :         tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
                               7468                 :          49912 :         tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
                               7469                 :          49912 :         AssignDumpId(&tblinfo[i].dobj);
 5085 bruce@momjian.us         7470                 :          49912 :         tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
 5012 rhaas@postgresql.org     7471                 :          99824 :         tblinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     7472                 :          49912 :             findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
 1421 tgl@sss.pgh.pa.us        7473                 :          49912 :         tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
                               7474                 :          49912 :         tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               7475                 :          49912 :         tblinfo[i].dacl.privtype = 0;
                               7476                 :          49912 :         tblinfo[i].dacl.initprivs = NULL;
 8571                          7477                 :          49912 :         tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
 1421                          7478                 :          49912 :         tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
 1396                          7479                 :          49912 :         tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
 1469                          7480                 :          49912 :         tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
 8571                          7481                 :          49912 :         tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
                               7482                 :          49912 :         tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
 4600 andrew@dunslane.net      7483                 :          49912 :         tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
 1421 tgl@sss.pgh.pa.us        7484         [ +  + ]:          49912 :         if (PQgetisnull(res, i, i_toastpages))
                               7485                 :          40123 :             tblinfo[i].toastpages = 0;
                               7486                 :                :         else
                               7487                 :           9789 :             tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
 8470                          7488         [ +  + ]:          49912 :         if (PQgetisnull(res, i, i_owning_tab))
                               7489                 :                :         {
 7996                          7490                 :          49497 :             tblinfo[i].owning_tab = InvalidOid;
 8470                          7491                 :          49497 :             tblinfo[i].owning_col = 0;
                               7492                 :                :         }
                               7493                 :                :         else
                               7494                 :                :         {
 7996                          7495                 :            415 :             tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
 8470                          7496                 :            415 :             tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
                               7497                 :                :         }
 5085 bruce@momjian.us         7498                 :          49912 :         tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
 1469 tgl@sss.pgh.pa.us        7499                 :          49912 :         tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
                               7500                 :          49912 :         tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
                               7501                 :          49912 :         tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
                               7502                 :          49912 :         tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
                               7503                 :          49912 :         tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
                               7504                 :          49912 :         tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
                               7505                 :          49912 :         tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
                               7506                 :          49912 :         tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
                               7507                 :          49912 :         tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
                               7508                 :          49912 :         tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
                               7509                 :          49912 :         tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
                               7510                 :          49912 :         tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
 5085 bruce@momjian.us         7511                 :          49912 :         tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
 1469 tgl@sss.pgh.pa.us        7512         [ +  + ]:          49912 :         if (PQgetisnull(res, i, i_checkoption))
 4484 sfrost@snowman.net       7513                 :          49866 :             tblinfo[i].checkoption = NULL;
                               7514                 :                :         else
                               7515                 :             46 :             tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
 5085 bruce@momjian.us         7516                 :          49912 :         tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
 1421 tgl@sss.pgh.pa.us        7517                 :          49912 :         tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
 1469                          7518                 :          49912 :         tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
 2427 andres@anarazel.de       7519         [ +  + ]:          49912 :         if (PQgetisnull(res, i, i_amname))
                               7520                 :          29958 :             tblinfo[i].amname = NULL;
                               7521                 :                :         else
                               7522                 :          19954 :             tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
 1469 tgl@sss.pgh.pa.us        7523                 :          49912 :         tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
                               7524                 :          49912 :         tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
                               7525                 :                : 
                               7526                 :                :         /* other fields were zeroed above */
                               7527                 :                : 
                               7528                 :                :         /*
                               7529                 :                :          * Decide whether we want to dump this table.
                               7530                 :                :          */
 7594                          7531         [ +  + ]:          49912 :         if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
 3491 sfrost@snowman.net       7532                 :            183 :             tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
                               7533                 :                :         else
                               7534                 :          49729 :             selectDumpableTable(&tblinfo[i], fout);
                               7535                 :                : 
                               7536                 :                :         /*
                               7537                 :                :          * Now, consider the table "interesting" if we need to dump its
                               7538                 :                :          * definition, data or its statistics.  Later on, we'll skip a lot of
                               7539                 :                :          * data collection for uninteresting tables.
                               7540                 :                :          *
                               7541                 :                :          * Note: the "interesting" flag will also be set by flagInhTables for
                               7542                 :                :          * parents of interesting tables, so that we collect necessary
                               7543                 :                :          * inheritance info even when the parents are not themselves being
                               7544                 :                :          * dumped.  This is the main reason why we need an "interesting" flag
                               7545                 :                :          * that's separate from the components-to-dump bitmask.
                               7546                 :                :          */
 1421 tgl@sss.pgh.pa.us        7547                 :          49912 :         tblinfo[i].interesting = (tblinfo[i].dobj.dump &
                               7548                 :                :                                   (DUMP_COMPONENT_DEFINITION |
                               7549                 :                :                                    DUMP_COMPONENT_DATA |
  249 jdavis@postgresql.or     7550                 :          49912 :                                    DUMP_COMPONENT_STATISTICS)) != 0;
                               7551                 :                : 
 1469 tgl@sss.pgh.pa.us        7552                 :          49912 :         tblinfo[i].dummy_view = false;  /* might get set during sort */
                               7553                 :          49912 :         tblinfo[i].postponed_def = false;   /* might get set during sort */
                               7554                 :                : 
                               7555                 :                :         /* Tables have data */
 1421                          7556                 :          49912 :         tblinfo[i].dobj.components |= DUMP_COMPONENT_DATA;
                               7557                 :                : 
                               7558                 :                :         /* Mark whether table has an ACL */
                               7559         [ +  + ]:          49912 :         if (!PQgetisnull(res, i, i_relacl))
                               7560                 :          40088 :             tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               7561                 :          49912 :         tblinfo[i].hascolumnACLs = false;   /* may get set later */
                               7562                 :                : 
                               7563                 :                :         /* Add statistics */
  249 jdavis@postgresql.or     7564         [ +  + ]:          49912 :         if (tblinfo[i].interesting)
                               7565                 :                :         {
                               7566                 :                :             RelStatsInfo *stats;
                               7567                 :                : 
  213                          7568                 :          13942 :             stats = getRelationStatistics(fout, &tblinfo[i].dobj,
                               7569                 :           6971 :                                           tblinfo[i].relpages,
                               7570                 :                :                                           PQgetvalue(res, i, i_reltuples),
                               7571                 :                :                                           relallvisible, relallfrozen,
                               7572                 :           6971 :                                           tblinfo[i].relkind, NULL, 0);
                               7573         [ +  + ]:           6971 :             if (tblinfo[i].relkind == RELKIND_MATVIEW)
                               7574                 :            401 :                 tblinfo[i].stats = stats;
                               7575                 :                :         }
                               7576                 :                : 
                               7577                 :                :         /*
                               7578                 :                :          * Read-lock target tables to make sure they aren't DROPPED or altered
                               7579                 :                :          * in schema before we get around to dumping them.
                               7580                 :                :          *
                               7581                 :                :          * Note that we don't explicitly lock parents of the target tables; we
                               7582                 :                :          * assume our lock on the child is enough to prevent schema
                               7583                 :                :          * alterations to parent tables.
                               7584                 :                :          *
                               7585                 :                :          * NOTE: it'd be kinda nice to lock other relations too, not only
                               7586                 :                :          * plain or partitioned tables, but the backend doesn't presently
                               7587                 :                :          * allow that.
                               7588                 :                :          *
                               7589                 :                :          * We only need to lock the table for certain components; see
                               7590                 :                :          * pg_dump.h
                               7591                 :                :          */
 1421 tgl@sss.pgh.pa.us        7592         [ +  + ]:          49912 :         if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
 1816                          7593         [ +  + ]:           6971 :             (tblinfo[i].relkind == RELKIND_RELATION ||
 1421                          7594         [ +  + ]:           1972 :              tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
                               7595                 :                :         {
                               7596                 :                :             /*
                               7597                 :                :              * Tables are locked in batches.  When dumping from a remote
                               7598                 :                :              * server this can save a significant amount of time by reducing
                               7599                 :                :              * the number of round trips.
                               7600                 :                :              */
 1028                          7601         [ +  + ]:           5593 :             if (query->len == 0)
                               7602                 :            126 :                 appendPQExpBuffer(query, "LOCK TABLE %s",
                               7603                 :            126 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7604                 :                :             else
                               7605                 :                :             {
                               7606                 :           5467 :                 appendPQExpBuffer(query, ", %s",
                               7607                 :           5467 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7608                 :                : 
                               7609                 :                :                 /* Arbitrarily end a batch when query length reaches 100K. */
                               7610         [ -  + ]:           5467 :                 if (query->len >= 100000)
                               7611                 :                :                 {
                               7612                 :                :                     /* Lock another batch of tables. */
 1028 tgl@sss.pgh.pa.us        7613                 :UBC           0 :                     appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7614                 :              0 :                     ExecuteSqlStatement(fout, query->data);
                               7615                 :              0 :                     resetPQExpBuffer(query);
                               7616                 :                :                 }
                               7617                 :                :             }
                               7618                 :                :         }
                               7619                 :                :     }
                               7620                 :                : 
 1028 tgl@sss.pgh.pa.us        7621         [ +  + ]:CBC         190 :     if (query->len != 0)
                               7622                 :                :     {
                               7623                 :                :         /* Lock the tables in the last batch. */
                               7624                 :            126 :         appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7625                 :            126 :         ExecuteSqlStatement(fout, query->data);
                               7626                 :                :     }
                               7627                 :                : 
 3302                          7628         [ +  + ]:            189 :     if (dopt->lockWaitTimeout)
                               7629                 :                :     {
 5011 rhaas@postgresql.org     7630                 :              2 :         ExecuteSqlStatement(fout, "SET statement_timeout = 0");
                               7631                 :                :     }
                               7632                 :                : 
 8571 tgl@sss.pgh.pa.us        7633                 :            189 :     PQclear(res);
                               7634                 :                : 
 4958                          7635                 :            189 :     destroyPQExpBuffer(query);
                               7636                 :                : 
                               7637                 :            189 :     return tblinfo;
                               7638                 :                : }
                               7639                 :                : 
                               7640                 :                : /*
                               7641                 :                :  * getOwnedSeqs
                               7642                 :                :  *    identify owned sequences and mark them as dumpable if owning table is
                               7643                 :                :  *
                               7644                 :                :  * We used to do this in getTables(), but it's better to do it after the
                               7645                 :                :  * index used by findTableByOid() has been set up.
                               7646                 :                :  */
                               7647                 :                : void
                               7648                 :            189 : getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
                               7649                 :                : {
                               7650                 :                :     int         i;
                               7651                 :                : 
                               7652                 :                :     /*
                               7653                 :                :      * Force sequences that are "owned" by table columns to be dumped whenever
                               7654                 :                :      * their owning table is being dumped.
                               7655                 :                :      */
                               7656         [ +  + ]:          49831 :     for (i = 0; i < numTables; i++)
                               7657                 :                :     {
 7007                          7658                 :          49642 :         TableInfo  *seqinfo = &tblinfo[i];
                               7659                 :                :         TableInfo  *owning_tab;
                               7660                 :                : 
                               7661         [ +  + ]:          49642 :         if (!OidIsValid(seqinfo->owning_tab))
                               7662                 :          49230 :             continue;           /* not an owned sequence */
                               7663                 :                : 
 4958                          7664                 :            412 :         owning_tab = findTableByOid(seqinfo->owning_tab);
 3216 sfrost@snowman.net       7665         [ -  + ]:            412 :         if (owning_tab == NULL)
 1298 tgl@sss.pgh.pa.us        7666                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                               7667                 :                :                      seqinfo->owning_tab, seqinfo->dobj.catId.oid);
                               7668                 :                : 
                               7669                 :                :         /*
                               7670                 :                :          * For an identity sequence, dump exactly the same components for the
                               7671                 :                :          * sequence as for the owning table.  This is important because we
                               7672                 :                :          * treat the identity sequence as an integral part of the table.  For
                               7673                 :                :          * example, there is not any DDL command that allows creation of such
                               7674                 :                :          * a sequence independently of the table.
                               7675                 :                :          *
                               7676                 :                :          * For other owned sequences such as serial sequences, we need to dump
                               7677                 :                :          * the components that are being dumped for the table and any
                               7678                 :                :          * components that the sequence is explicitly marked with.
                               7679                 :                :          *
                               7680                 :                :          * We can't simply use the set of components which are being dumped
                               7681                 :                :          * for the table as the table might be in an extension (and only the
                               7682                 :                :          * non-extension components, eg: ACLs if changed, security labels, and
                               7683                 :                :          * policies, are being dumped) while the sequence is not (and
                               7684                 :                :          * therefore the definition and other components should also be
                               7685                 :                :          * dumped).
                               7686                 :                :          *
                               7687                 :                :          * If the sequence is part of the extension then it should be properly
                               7688                 :                :          * marked by checkExtensionMembership() and this will be a no-op as
                               7689                 :                :          * the table will be equivalently marked.
                               7690                 :                :          */
  318 tgl@sss.pgh.pa.us        7691         [ +  + ]:CBC         412 :         if (seqinfo->is_identity_sequence)
                               7692                 :            199 :             seqinfo->dobj.dump = owning_tab->dobj.dump;
                               7693                 :                :         else
                               7694                 :            213 :             seqinfo->dobj.dump |= owning_tab->dobj.dump;
                               7695                 :                : 
                               7696                 :                :         /* Make sure that necessary data is available if we're dumping it */
 3375 sfrost@snowman.net       7697         [ +  + ]:            412 :         if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
                               7698                 :                :         {
 4958 tgl@sss.pgh.pa.us        7699                 :            316 :             seqinfo->interesting = true;
  318                          7700                 :            316 :             owning_tab->interesting = true;
                               7701                 :                :         }
                               7702                 :                :     }
10702 scrappy@hub.org          7703                 :            189 : }
                               7704                 :                : 
                               7705                 :                : /*
                               7706                 :                :  * getInherits
                               7707                 :                :  *    read all the inheritance information
                               7708                 :                :  * from the system catalogs return them in the InhInfo* structure
                               7709                 :                :  *
                               7710                 :                :  * numInherits is set to the number of pairs read in
                               7711                 :                :  */
                               7712                 :                : InhInfo *
 5012 rhaas@postgresql.org     7713                 :            189 : getInherits(Archive *fout, int *numInherits)
                               7714                 :                : {
                               7715                 :                :     PGresult   *res;
                               7716                 :                :     int         ntups;
                               7717                 :                :     int         i;
 9329 bruce@momjian.us         7718                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               7719                 :                :     InhInfo    *inhinfo;
                               7720                 :                : 
                               7721                 :                :     int         i_inhrelid;
                               7722                 :                :     int         i_inhparent;
                               7723                 :                : 
                               7724                 :                :     /* find all the inheritance information */
 3098 sfrost@snowman.net       7725                 :            189 :     appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
                               7726                 :                : 
 5011 rhaas@postgresql.org     7727                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7728                 :                : 
10277 bruce@momjian.us         7729                 :            189 :     ntups = PQntuples(res);
                               7730                 :                : 
                               7731                 :            189 :     *numInherits = ntups;
                               7732                 :                : 
 5085                          7733                 :            189 :     inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
                               7734                 :                : 
 9471                          7735                 :            189 :     i_inhrelid = PQfnumber(res, "inhrelid");
10277                          7736                 :            189 :     i_inhparent = PQfnumber(res, "inhparent");
                               7737                 :                : 
                               7738         [ +  + ]:           3557 :     for (i = 0; i < ntups; i++)
                               7739                 :                :     {
 7996 tgl@sss.pgh.pa.us        7740                 :           3368 :         inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
                               7741                 :           3368 :         inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
                               7742                 :                :     }
                               7743                 :                : 
10277 bruce@momjian.us         7744                 :            189 :     PQclear(res);
                               7745                 :                : 
 8851 tgl@sss.pgh.pa.us        7746                 :            189 :     destroyPQExpBuffer(query);
                               7747                 :                : 
10277 bruce@momjian.us         7748                 :            189 :     return inhinfo;
                               7749                 :                : }
                               7750                 :                : 
                               7751                 :                : /*
                               7752                 :                :  * getPartitioningInfo
                               7753                 :                :  *    get information about partitioning
                               7754                 :                :  *
                               7755                 :                :  * For the most part, we only collect partitioning info about tables we
                               7756                 :                :  * intend to dump.  However, this function has to consider all partitioned
                               7757                 :                :  * tables in the database, because we need to know about parents of partitions
                               7758                 :                :  * we are going to dump even if the parents themselves won't be dumped.
                               7759                 :                :  *
                               7760                 :                :  * Specifically, what we need to know is whether each partitioned table
                               7761                 :                :  * has an "unsafe" partitioning scheme that requires us to force
                               7762                 :                :  * load-via-partition-root mode for its children.  Currently the only case
                               7763                 :                :  * for which we force that is hash partitioning on enum columns, since the
                               7764                 :                :  * hash codes depend on enum value OIDs which won't be replicated across
                               7765                 :                :  * dump-and-reload.  There are other cases in which load-via-partition-root
                               7766                 :                :  * might be necessary, but we expect users to cope with them.
                               7767                 :                :  */
                               7768                 :                : void
  955 tgl@sss.pgh.pa.us        7769                 :            189 : getPartitioningInfo(Archive *fout)
                               7770                 :                : {
                               7771                 :                :     PQExpBuffer query;
                               7772                 :                :     PGresult   *res;
                               7773                 :                :     int         ntups;
                               7774                 :                : 
                               7775                 :                :     /* hash partitioning didn't exist before v11 */
                               7776         [ -  + ]:            189 :     if (fout->remoteVersion < 110000)
  955 tgl@sss.pgh.pa.us        7777                 :UBC           0 :         return;
                               7778                 :                :     /* needn't bother if not dumping data */
  336 nathan@postgresql.or     7779         [ +  + ]:CBC         189 :     if (!fout->dopt->dumpData)
  955 tgl@sss.pgh.pa.us        7780                 :             40 :         return;
                               7781                 :                : 
                               7782                 :            149 :     query = createPQExpBuffer();
                               7783                 :                : 
                               7784                 :                :     /*
                               7785                 :                :      * Unsafe partitioning schemes are exactly those for which hash enum_ops
                               7786                 :                :      * appears among the partition opclasses.  We needn't check partstrat.
                               7787                 :                :      *
                               7788                 :                :      * Note that this query may well retrieve info about tables we aren't
                               7789                 :                :      * going to dump and hence have no lock on.  That's okay since we need not
                               7790                 :                :      * invoke any unsafe server-side functions.
                               7791                 :                :      */
                               7792                 :            149 :     appendPQExpBufferStr(query,
                               7793                 :                :                          "SELECT partrelid FROM pg_partitioned_table WHERE\n"
                               7794                 :                :                          "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
                               7795                 :                :                          "ON c.opcmethod = a.oid\n"
                               7796                 :                :                          "WHERE opcname = 'enum_ops' "
                               7797                 :                :                          "AND opcnamespace = 'pg_catalog'::regnamespace "
                               7798                 :                :                          "AND amname = 'hash') = ANY(partclass)");
                               7799                 :                : 
                               7800                 :            149 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7801                 :                : 
                               7802                 :            149 :     ntups = PQntuples(res);
                               7803                 :                : 
                               7804         [ +  + ]:            192 :     for (int i = 0; i < ntups; i++)
                               7805                 :                :     {
                               7806                 :             43 :         Oid         tabrelid = atooid(PQgetvalue(res, i, 0));
                               7807                 :                :         TableInfo  *tbinfo;
                               7808                 :                : 
                               7809                 :             43 :         tbinfo = findTableByOid(tabrelid);
                               7810         [ -  + ]:             43 :         if (tbinfo == NULL)
  955 tgl@sss.pgh.pa.us        7811                 :UBC           0 :             pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
                               7812                 :                :                      tabrelid);
  955 tgl@sss.pgh.pa.us        7813                 :CBC          43 :         tbinfo->unsafe_partitions = true;
                               7814                 :                :     }
                               7815                 :                : 
                               7816                 :            149 :     PQclear(res);
                               7817                 :                : 
                               7818                 :            149 :     destroyPQExpBuffer(query);
                               7819                 :                : }
                               7820                 :                : 
                               7821                 :                : /*
                               7822                 :                :  * getIndexes
                               7823                 :                :  *    get information about every index on a dumpable table
                               7824                 :                :  *
                               7825                 :                :  * Note: index data is not returned directly to the caller, but it
                               7826                 :                :  * does get entered into the DumpableObject tables.
                               7827                 :                :  */
                               7828                 :                : void
 5012 rhaas@postgresql.org     7829                 :            189 : getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                               7830                 :                : {
 7996 tgl@sss.pgh.pa.us        7831                 :            189 :     PQExpBuffer query = createPQExpBuffer();
 1421                          7832                 :            189 :     PQExpBuffer tbloids = createPQExpBuffer();
                               7833                 :                :     PGresult   *res;
                               7834                 :                :     int         ntups;
                               7835                 :                :     int         curtblindx;
                               7836                 :                :     IndxInfo   *indxinfo;
                               7837                 :                :     int         i_tableoid,
                               7838                 :                :                 i_oid,
                               7839                 :                :                 i_indrelid,
                               7840                 :                :                 i_indexname,
                               7841                 :                :                 i_relpages,
                               7842                 :                :                 i_reltuples,
                               7843                 :                :                 i_relallvisible,
                               7844                 :                :                 i_relallfrozen,
                               7845                 :                :                 i_parentidx,
                               7846                 :                :                 i_indexdef,
                               7847                 :                :                 i_indnkeyatts,
                               7848                 :                :                 i_indnatts,
                               7849                 :                :                 i_indkey,
                               7850                 :                :                 i_indisclustered,
                               7851                 :                :                 i_indisreplident,
                               7852                 :                :                 i_indnullsnotdistinct,
                               7853                 :                :                 i_contype,
                               7854                 :                :                 i_conname,
                               7855                 :                :                 i_condeferrable,
                               7856                 :                :                 i_condeferred,
                               7857                 :                :                 i_conperiod,
                               7858                 :                :                 i_contableoid,
                               7859                 :                :                 i_conoid,
                               7860                 :                :                 i_condef,
                               7861                 :                :                 i_indattnames,
                               7862                 :                :                 i_tablespace,
                               7863                 :                :                 i_indreloptions,
                               7864                 :                :                 i_indstatcols,
                               7865                 :                :                 i_indstatvals;
                               7866                 :                : 
                               7867                 :                :     /*
                               7868                 :                :      * We want to perform just one query against pg_index.  However, we
                               7869                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               7870                 :                :      * the client side, because some of the server-side functions we need
                               7871                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               7872                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               7873                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               7874                 :                :      */
                               7875                 :            189 :     appendPQExpBufferChar(tbloids, '{');
                               7876         [ +  + ]:          49831 :     for (int i = 0; i < numTables; i++)
                               7877                 :                :     {
 7996                          7878                 :          49642 :         TableInfo  *tbinfo = &tblinfo[i];
                               7879                 :                : 
 4621 kgrittn@postgresql.o     7880         [ +  + ]:          49642 :         if (!tbinfo->hasindex)
 7996 tgl@sss.pgh.pa.us        7881                 :          35168 :             continue;
                               7882                 :                : 
                               7883                 :                :         /*
                               7884                 :                :          * We can ignore indexes of uninteresting tables.
                               7885                 :                :          */
 1421                          7886         [ +  + ]:          14474 :         if (!tbinfo->interesting)
 7996                          7887                 :          12483 :             continue;
                               7888                 :                : 
                               7889                 :                :         /* OK, we need info for this table */
 1421                          7890         [ +  + ]:           1991 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               7891                 :           1913 :             appendPQExpBufferChar(tbloids, ',');
                               7892                 :           1991 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               7893                 :                :     }
                               7894                 :            189 :     appendPQExpBufferChar(tbloids, '}');
                               7895                 :                : 
 1147 drowley@postgresql.o     7896                 :            189 :     appendPQExpBufferStr(query,
                               7897                 :                :                          "SELECT t.tableoid, t.oid, i.indrelid, "
                               7898                 :                :                          "t.relname AS indexname, "
                               7899                 :                :                          "t.relpages, t.reltuples, t.relallvisible, ");
                               7900                 :                : 
  211 jdavis@postgresql.or     7901         [ +  - ]:            189 :     if (fout->remoteVersion >= 180000)
                               7902                 :            189 :         appendPQExpBufferStr(query, "t.relallfrozen, ");
                               7903                 :                :     else
  211 jdavis@postgresql.or     7904                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS relallfrozen, ");
                               7905                 :                : 
  211 jdavis@postgresql.or     7906                 :CBC         189 :     appendPQExpBufferStr(query,
                               7907                 :                :                          "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                               7908                 :                :                          "i.indkey, i.indisclustered, "
                               7909                 :                :                          "c.contype, c.conname, "
                               7910                 :                :                          "c.condeferrable, c.condeferred, "
                               7911                 :                :                          "c.tableoid AS contableoid, "
                               7912                 :                :                          "c.oid AS conoid, "
                               7913                 :                :                          "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
                               7914                 :                :                          "CASE WHEN i.indexprs IS NOT NULL THEN "
                               7915                 :                :                          "(SELECT pg_catalog.array_agg(attname ORDER BY attnum)"
                               7916                 :                :                          "  FROM pg_catalog.pg_attribute "
                               7917                 :                :                          "  WHERE attrelid = i.indexrelid) "
                               7918                 :                :                          "ELSE NULL END AS indattnames, "
                               7919                 :                :                          "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
                               7920                 :                :                          "t.reloptions AS indreloptions, ");
                               7921                 :                : 
                               7922                 :                : 
 1407 peter@eisentraut.org     7923         [ +  - ]:            189 :     if (fout->remoteVersion >= 90400)
 1147 drowley@postgresql.o     7924                 :            189 :         appendPQExpBufferStr(query,
                               7925                 :                :                              "i.indisreplident, ");
                               7926                 :                :     else
 1147 drowley@postgresql.o     7927                 :UBC           0 :         appendPQExpBufferStr(query,
                               7928                 :                :                              "false AS indisreplident, ");
                               7929                 :                : 
 1407 peter@eisentraut.org     7930         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 110000)
 1147 drowley@postgresql.o     7931                 :            189 :         appendPQExpBufferStr(query,
                               7932                 :                :                              "inh.inhparent AS parentidx, "
                               7933                 :                :                              "i.indnkeyatts AS indnkeyatts, "
                               7934                 :                :                              "i.indnatts AS indnatts, "
                               7935                 :                :                              "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
                               7936                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7937                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7938                 :                :                              "    attstattarget >= 0) AS indstatcols, "
                               7939                 :                :                              "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
                               7940                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7941                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7942                 :                :                              "    attstattarget >= 0) AS indstatvals, ");
                               7943                 :                :     else
 1147 drowley@postgresql.o     7944                 :UBC           0 :         appendPQExpBufferStr(query,
                               7945                 :                :                              "0 AS parentidx, "
                               7946                 :                :                              "i.indnatts AS indnkeyatts, "
                               7947                 :                :                              "i.indnatts AS indnatts, "
                               7948                 :                :                              "'' AS indstatcols, "
                               7949                 :                :                              "'' AS indstatvals, ");
                               7950                 :                : 
 1362 peter@eisentraut.org     7951         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 150000)
 1147 drowley@postgresql.o     7952                 :            189 :         appendPQExpBufferStr(query,
                               7953                 :                :                              "i.indnullsnotdistinct, ");
                               7954                 :                :     else
 1147 drowley@postgresql.o     7955                 :UBC           0 :         appendPQExpBufferStr(query,
                               7956                 :                :                              "false AS indnullsnotdistinct, ");
                               7957                 :                : 
  405 peter@eisentraut.org     7958         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 180000)
                               7959                 :            189 :         appendPQExpBufferStr(query,
                               7960                 :                :                              "c.conperiod ");
                               7961                 :                :     else
  405 peter@eisentraut.org     7962                 :UBC           0 :         appendPQExpBufferStr(query,
                               7963                 :                :                              "NULL AS conperiod ");
                               7964                 :                : 
                               7965                 :                :     /*
                               7966                 :                :      * The point of the messy-looking outer join is to find a constraint that
                               7967                 :                :      * is related by an internal dependency link to the index. If we find one,
                               7968                 :                :      * create a CONSTRAINT entry linked to the INDEX entry.  We assume an
                               7969                 :                :      * index won't have more than one internal dependency.
                               7970                 :                :      *
                               7971                 :                :      * Note: the check on conrelid is redundant, but useful because that
                               7972                 :                :      * column is indexed while conindid is not.
                               7973                 :                :      */
 1421 tgl@sss.pgh.pa.us        7974         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 110000)
                               7975                 :                :     {
                               7976                 :            189 :         appendPQExpBuffer(query,
                               7977                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7978                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               7979                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               7980                 :                :                           "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
                               7981                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               7982                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               7983                 :                :                           "i.indexrelid = c.conindid AND "
                               7984                 :                :                           "c.contype IN ('p','u','x')) "
                               7985                 :                :                           "LEFT JOIN pg_catalog.pg_inherits inh "
                               7986                 :                :                           "ON (inh.inhrelid = indexrelid) "
                               7987                 :                :                           "WHERE (i.indisvalid OR t2.relkind = 'p') "
                               7988                 :                :                           "AND i.indisready "
                               7989                 :                :                           "ORDER BY i.indrelid, indexname",
                               7990                 :                :                           tbloids->data);
                               7991                 :                :     }
                               7992                 :                :     else
                               7993                 :                :     {
                               7994                 :                :         /*
                               7995                 :                :          * the test on indisready is necessary in 9.2, and harmless in
                               7996                 :                :          * earlier/later versions
                               7997                 :                :          */
 1421 tgl@sss.pgh.pa.us        7998                 :UBC           0 :         appendPQExpBuffer(query,
                               7999                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8000                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               8001                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               8002                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               8003                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               8004                 :                :                           "i.indexrelid = c.conindid AND "
                               8005                 :                :                           "c.contype IN ('p','u','x')) "
                               8006                 :                :                           "WHERE i.indisvalid AND i.indisready "
                               8007                 :                :                           "ORDER BY i.indrelid, indexname",
                               8008                 :                :                           tbloids->data);
                               8009                 :                :     }
                               8010                 :                : 
 1421 tgl@sss.pgh.pa.us        8011                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8012                 :                : 
                               8013                 :            189 :     ntups = PQntuples(res);
                               8014                 :                : 
                               8015                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8016                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8017                 :            189 :     i_indrelid = PQfnumber(res, "indrelid");
                               8018                 :            189 :     i_indexname = PQfnumber(res, "indexname");
  244 jdavis@postgresql.or     8019                 :            189 :     i_relpages = PQfnumber(res, "relpages");
                               8020                 :            189 :     i_reltuples = PQfnumber(res, "reltuples");
                               8021                 :            189 :     i_relallvisible = PQfnumber(res, "relallvisible");
  211                          8022                 :            189 :     i_relallfrozen = PQfnumber(res, "relallfrozen");
 1421 tgl@sss.pgh.pa.us        8023                 :            189 :     i_parentidx = PQfnumber(res, "parentidx");
                               8024                 :            189 :     i_indexdef = PQfnumber(res, "indexdef");
                               8025                 :            189 :     i_indnkeyatts = PQfnumber(res, "indnkeyatts");
                               8026                 :            189 :     i_indnatts = PQfnumber(res, "indnatts");
                               8027                 :            189 :     i_indkey = PQfnumber(res, "indkey");
                               8028                 :            189 :     i_indisclustered = PQfnumber(res, "indisclustered");
                               8029                 :            189 :     i_indisreplident = PQfnumber(res, "indisreplident");
 1362 peter@eisentraut.org     8030                 :            189 :     i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
 1421 tgl@sss.pgh.pa.us        8031                 :            189 :     i_contype = PQfnumber(res, "contype");
                               8032                 :            189 :     i_conname = PQfnumber(res, "conname");
                               8033                 :            189 :     i_condeferrable = PQfnumber(res, "condeferrable");
                               8034                 :            189 :     i_condeferred = PQfnumber(res, "condeferred");
  405 peter@eisentraut.org     8035                 :            189 :     i_conperiod = PQfnumber(res, "conperiod");
 1421 tgl@sss.pgh.pa.us        8036                 :            189 :     i_contableoid = PQfnumber(res, "contableoid");
                               8037                 :            189 :     i_conoid = PQfnumber(res, "conoid");
                               8038                 :            189 :     i_condef = PQfnumber(res, "condef");
  243                          8039                 :            189 :     i_indattnames = PQfnumber(res, "indattnames");
 1421                          8040                 :            189 :     i_tablespace = PQfnumber(res, "tablespace");
                               8041                 :            189 :     i_indreloptions = PQfnumber(res, "indreloptions");
                               8042                 :            189 :     i_indstatcols = PQfnumber(res, "indstatcols");
                               8043                 :            189 :     i_indstatvals = PQfnumber(res, "indstatvals");
                               8044                 :                : 
                               8045                 :            189 :     indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
                               8046                 :                : 
                               8047                 :                :     /*
                               8048                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               8049                 :                :      * j is handled by the inner loop.
                               8050                 :                :      */
                               8051                 :            189 :     curtblindx = -1;
                               8052         [ +  + ]:           2160 :     for (int j = 0; j < ntups;)
                               8053                 :                :     {
                               8054                 :           1971 :         Oid         indrelid = atooid(PQgetvalue(res, j, i_indrelid));
                               8055                 :           1971 :         TableInfo  *tbinfo = NULL;
  243                          8056                 :           1971 :         char      **indAttNames = NULL;
                               8057                 :           1971 :         int         nindAttNames = 0;
                               8058                 :                :         int         numinds;
                               8059                 :                : 
                               8060                 :                :         /* Count rows for this table */
 1421                          8061         [ +  + ]:           2583 :         for (numinds = 1; numinds < ntups - j; numinds++)
                               8062         [ +  + ]:           2505 :             if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
                               8063                 :           1893 :                 break;
                               8064                 :                : 
                               8065                 :                :         /*
                               8066                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8067                 :                :          * order.
                               8068                 :                :          */
                               8069         [ +  - ]:          23103 :         while (++curtblindx < numTables)
                               8070                 :                :         {
                               8071                 :          23103 :             tbinfo = &tblinfo[curtblindx];
                               8072         [ +  + ]:          23103 :             if (tbinfo->dobj.catId.oid == indrelid)
                               8073                 :           1971 :                 break;
                               8074                 :                :         }
                               8075         [ -  + ]:           1971 :         if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        8076                 :UBC           0 :             pg_fatal("unrecognized table OID %u", indrelid);
                               8077                 :                :         /* cross-check that we only got requested tables */
 1421 tgl@sss.pgh.pa.us        8078         [ +  - ]:CBC        1971 :         if (!tbinfo->hasindex ||
                               8079         [ -  + ]:           1971 :             !tbinfo->interesting)
 1298 tgl@sss.pgh.pa.us        8080                 :UBC           0 :             pg_fatal("unexpected index data for table \"%s\"",
                               8081                 :                :                      tbinfo->dobj.name);
                               8082                 :                : 
                               8083                 :                :         /* Save data for this table */
 1421 tgl@sss.pgh.pa.us        8084                 :CBC        1971 :         tbinfo->indexes = indxinfo + j;
                               8085                 :           1971 :         tbinfo->numIndexes = numinds;
                               8086                 :                : 
                               8087         [ +  + ]:           4554 :         for (int c = 0; c < numinds; c++, j++)
                               8088                 :                :         {
                               8089                 :                :             char        contype;
                               8090                 :                :             char        indexkind;
                               8091                 :                :             RelStatsInfo *relstats;
  244 jdavis@postgresql.or     8092                 :           2583 :             int32       relpages = atoi(PQgetvalue(res, j, i_relpages));
                               8093                 :           2583 :             int32       relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
  211                          8094                 :           2583 :             int32       relallfrozen = atoi(PQgetvalue(res, j, i_relallfrozen));
                               8095                 :                : 
 7996 tgl@sss.pgh.pa.us        8096                 :           2583 :             indxinfo[j].dobj.objType = DO_INDEX;
                               8097                 :           2583 :             indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               8098                 :           2583 :             indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               8099                 :           2583 :             AssignDumpId(&indxinfo[j].dobj);
 2838 alvherre@alvh.no-ip.     8100                 :           2583 :             indxinfo[j].dobj.dump = tbinfo->dobj.dump;
 5085 bruce@momjian.us         8101                 :           2583 :             indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
 7908 tgl@sss.pgh.pa.us        8102                 :           2583 :             indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7996                          8103                 :           2583 :             indxinfo[j].indextable = tbinfo;
 5085 bruce@momjian.us         8104                 :           2583 :             indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 2750 heikki.linnakangas@i     8105                 :           2583 :             indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
 2760 teodor@sigaev.ru         8106                 :           2583 :             indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
 5085 bruce@momjian.us         8107                 :           2583 :             indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
 3586 tgl@sss.pgh.pa.us        8108                 :           2583 :             indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
 2505 michael@paquier.xyz      8109                 :           2583 :             indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
                               8110                 :           2583 :             indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
 2760 teodor@sigaev.ru         8111                 :           2583 :             indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
 7996 tgl@sss.pgh.pa.us        8112                 :           2583 :             parseOidArray(PQgetvalue(res, j, i_indkey),
 2760 teodor@sigaev.ru         8113                 :           2583 :                           indxinfo[j].indkeys, indxinfo[j].indnattrs);
 7996 tgl@sss.pgh.pa.us        8114                 :           2583 :             indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
 4371 rhaas@postgresql.org     8115                 :           2583 :             indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
 1362 peter@eisentraut.org     8116                 :           2583 :             indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
 2838 alvherre@alvh.no-ip.     8117                 :           2583 :             indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
 1992 tgl@sss.pgh.pa.us        8118                 :           2583 :             indxinfo[j].partattaches = (SimplePtrList)
                               8119                 :                :             {
                               8120                 :                :                 NULL, NULL
                               8121                 :                :             };
                               8122                 :                : 
  249 jdavis@postgresql.or     8123         [ +  + ]:           2583 :             if (indxinfo[j].parentidx == 0)
                               8124                 :           2019 :                 indexkind = RELKIND_INDEX;
                               8125                 :                :             else
                               8126                 :            564 :                 indexkind = RELKIND_PARTITIONED_INDEX;
                               8127                 :                : 
  243 tgl@sss.pgh.pa.us        8128         [ +  + ]:           2583 :             if (!PQgetisnull(res, j, i_indattnames))
                               8129                 :                :             {
                               8130         [ -  + ]:            146 :                 if (!parsePGArray(PQgetvalue(res, j, i_indattnames),
                               8131                 :                :                                   &indAttNames, &nindAttNames))
  243 tgl@sss.pgh.pa.us        8132                 :UBC           0 :                     pg_fatal("could not parse %s array", "indattnames");
                               8133                 :                :             }
                               8134                 :                : 
  244 jdavis@postgresql.or     8135                 :CBC        2583 :             relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
                               8136                 :                :                                              PQgetvalue(res, j, i_reltuples),
                               8137                 :                :                                              relallvisible, relallfrozen, indexkind,
                               8138                 :                :                                              indAttNames, nindAttNames);
                               8139                 :                : 
  243 tgl@sss.pgh.pa.us        8140                 :           2583 :             contype = *(PQgetvalue(res, j, i_contype));
 5803                          8141   [ +  +  +  +  :           2583 :             if (contype == 'p' || contype == 'u' || contype == 'x')
                                              +  + ]
 7996                          8142                 :           1501 :             {
                               8143                 :                :                 /*
                               8144                 :                :                  * If we found a constraint matching the index, create an
                               8145                 :                :                  * entry for it.
                               8146                 :                :                  */
                               8147                 :                :                 ConstraintInfo *constrinfo;
                               8148                 :                : 
 1464                          8149                 :           1501 :                 constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
                               8150                 :           1501 :                 constrinfo->dobj.objType = DO_CONSTRAINT;
                               8151                 :           1501 :                 constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               8152                 :           1501 :                 constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               8153                 :           1501 :                 AssignDumpId(&constrinfo->dobj);
                               8154                 :           1501 :                 constrinfo->dobj.dump = tbinfo->dobj.dump;
                               8155                 :           1501 :                 constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               8156                 :           1501 :                 constrinfo->dobj.namespace = tbinfo->dobj.namespace;
                               8157                 :           1501 :                 constrinfo->contable = tbinfo;
                               8158                 :           1501 :                 constrinfo->condomain = NULL;
                               8159                 :           1501 :                 constrinfo->contype = contype;
 5803                          8160         [ +  + ]:           1501 :                 if (contype == 'x')
 1464                          8161                 :             10 :                     constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               8162                 :                :                 else
                               8163                 :           1491 :                     constrinfo->condef = NULL;
                               8164                 :           1501 :                 constrinfo->confrelid = InvalidOid;
                               8165                 :           1501 :                 constrinfo->conindex = indxinfo[j].dobj.dumpId;
                               8166                 :           1501 :                 constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
                               8167                 :           1501 :                 constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
  405 peter@eisentraut.org     8168                 :           1501 :                 constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
 1464 tgl@sss.pgh.pa.us        8169                 :           1501 :                 constrinfo->conislocal = true;
                               8170                 :           1501 :                 constrinfo->separate = true;
                               8171                 :                : 
                               8172                 :           1501 :                 indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
  249 jdavis@postgresql.or     8173         [ +  + ]:           1501 :                 if (relstats != NULL)
                               8174                 :            526 :                     addObjectDependency(&relstats->dobj, constrinfo->dobj.dumpId);
                               8175                 :                :             }
                               8176                 :                :             else
                               8177                 :                :             {
                               8178                 :                :                 /* Plain secondary index */
 7996 tgl@sss.pgh.pa.us        8179                 :           1082 :                 indxinfo[j].indexconstraint = 0;
                               8180                 :                :             }
                               8181                 :                :         }
                               8182                 :                :     }
                               8183                 :                : 
 1421                          8184                 :            189 :     PQclear(res);
                               8185                 :                : 
 7996                          8186                 :            189 :     destroyPQExpBuffer(query);
 1421                          8187                 :            189 :     destroyPQExpBuffer(tbloids);
 7996                          8188                 :            189 : }
                               8189                 :                : 
                               8190                 :                : /*
                               8191                 :                :  * getExtendedStatistics
                               8192                 :                :  *    get information about extended-statistics objects.
                               8193                 :                :  *
                               8194                 :                :  * Note: extended statistics data is not returned directly to the caller, but
                               8195                 :                :  * it does get entered into the DumpableObject tables.
                               8196                 :                :  */
                               8197                 :                : void
 2815                          8198                 :            189 : getExtendedStatistics(Archive *fout)
                               8199                 :                : {
                               8200                 :                :     PQExpBuffer query;
                               8201                 :                :     PGresult   *res;
                               8202                 :                :     StatsExtInfo *statsextinfo;
                               8203                 :                :     int         ntups;
                               8204                 :                :     int         i_tableoid;
                               8205                 :                :     int         i_oid;
                               8206                 :                :     int         i_stxname;
                               8207                 :                :     int         i_stxnamespace;
                               8208                 :                :     int         i_stxowner;
                               8209                 :                :     int         i_stxrelid;
                               8210                 :                :     int         i_stattarget;
                               8211                 :                :     int         i;
                               8212                 :                : 
                               8213                 :                :     /* Extended statistics were new in v10 */
 3139 alvherre@alvh.no-ip.     8214         [ -  + ]:            189 :     if (fout->remoteVersion < 100000)
 3139 alvherre@alvh.no-ip.     8215                 :UBC           0 :         return;
                               8216                 :                : 
 3139 alvherre@alvh.no-ip.     8217                 :CBC         189 :     query = createPQExpBuffer();
                               8218                 :                : 
 2239 tomas.vondra@postgre     8219         [ -  + ]:            189 :     if (fout->remoteVersion < 130000)
 1147 drowley@postgresql.o     8220                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               8221                 :                :                              "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
                               8222                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               8223                 :                :     else
 1147 drowley@postgresql.o     8224                 :CBC         189 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               8225                 :                :                              "stxnamespace, stxowner, stxrelid, stxstattarget "
                               8226                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               8227                 :                : 
 2815 tgl@sss.pgh.pa.us        8228                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8229                 :                : 
                               8230                 :            189 :     ntups = PQntuples(res);
                               8231                 :                : 
                               8232                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8233                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8234                 :            189 :     i_stxname = PQfnumber(res, "stxname");
                               8235                 :            189 :     i_stxnamespace = PQfnumber(res, "stxnamespace");
 1396                          8236                 :            189 :     i_stxowner = PQfnumber(res, "stxowner");
  668                          8237                 :            189 :     i_stxrelid = PQfnumber(res, "stxrelid");
 2239 tomas.vondra@postgre     8238                 :            189 :     i_stattarget = PQfnumber(res, "stxstattarget");
                               8239                 :                : 
 2815 tgl@sss.pgh.pa.us        8240                 :            189 :     statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
                               8241                 :                : 
                               8242         [ +  + ]:            352 :     for (i = 0; i < ntups; i++)
                               8243                 :                :     {
                               8244                 :            163 :         statsextinfo[i].dobj.objType = DO_STATSEXT;
                               8245                 :            163 :         statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8246                 :            163 :         statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8247                 :            163 :         AssignDumpId(&statsextinfo[i].dobj);
                               8248                 :            163 :         statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
                               8249                 :            326 :         statsextinfo[i].dobj.namespace =
 1889 peter@eisentraut.org     8250                 :            163 :             findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
 1396 tgl@sss.pgh.pa.us        8251                 :            163 :         statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
  668                          8252                 :            326 :         statsextinfo[i].stattable =
                               8253                 :            163 :             findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
  589 peter@eisentraut.org     8254         [ +  + ]:            163 :         if (PQgetisnull(res, i, i_stattarget))
                               8255                 :            118 :             statsextinfo[i].stattarget = -1;
                               8256                 :                :         else
                               8257                 :             45 :             statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
                               8258                 :                : 
                               8259                 :                :         /* Decide whether we want to dump it */
  668 tgl@sss.pgh.pa.us        8260                 :            163 :         selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
                               8261                 :                :     }
                               8262                 :                : 
 2815                          8263                 :            189 :     PQclear(res);
 3139 alvherre@alvh.no-ip.     8264                 :            189 :     destroyPQExpBuffer(query);
                               8265                 :                : }
                               8266                 :                : 
                               8267                 :                : /*
                               8268                 :                :  * getConstraints
                               8269                 :                :  *
                               8270                 :                :  * Get info about constraints on dumpable tables.
                               8271                 :                :  *
                               8272                 :                :  * Currently handles foreign keys only.
                               8273                 :                :  * Unique and primary key constraints are handled with indexes,
                               8274                 :                :  * while check constraints are processed in getTableAttrs().
                               8275                 :                :  */
                               8276                 :                : void
 5012 rhaas@postgresql.org     8277                 :            189 : getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
                               8278                 :                : {
 1421 tgl@sss.pgh.pa.us        8279                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               8280                 :            189 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8281                 :                :     PGresult   *res;
                               8282                 :                :     int         ntups;
                               8283                 :                :     int         curtblindx;
                               8284                 :            189 :     TableInfo  *tbinfo = NULL;
                               8285                 :                :     ConstraintInfo *constrinfo;
                               8286                 :                :     int         i_contableoid,
                               8287                 :                :                 i_conoid,
                               8288                 :                :                 i_conrelid,
                               8289                 :                :                 i_conname,
                               8290                 :                :                 i_confrelid,
                               8291                 :                :                 i_conindid,
                               8292                 :                :                 i_condef;
                               8293                 :                : 
                               8294                 :                :     /*
                               8295                 :                :      * We want to perform just one query against pg_constraint.  However, we
                               8296                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               8297                 :                :      * the client side, because some of the server-side functions we need
                               8298                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8299                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8300                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8301                 :                :      */
                               8302                 :            189 :     appendPQExpBufferChar(tbloids, '{');
                               8303         [ +  + ]:          49831 :     for (int i = 0; i < numTables; i++)
                               8304                 :                :     {
 1164 drowley@postgresql.o     8305                 :          49642 :         TableInfo  *tinfo = &tblinfo[i];
                               8306                 :                : 
  208 peter@eisentraut.org     8307         [ +  + ]:          49642 :         if (!(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7996 tgl@sss.pgh.pa.us        8308                 :          42722 :             continue;
                               8309                 :                : 
                               8310                 :                :         /* OK, we need info for this table */
 1421                          8311         [ +  + ]:           6920 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8312                 :           6793 :             appendPQExpBufferChar(tbloids, ',');
 1164 drowley@postgresql.o     8313                 :           6920 :         appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
                               8314                 :                :     }
 1421 tgl@sss.pgh.pa.us        8315                 :            189 :     appendPQExpBufferChar(tbloids, '}');
                               8316                 :                : 
                               8317                 :            189 :     appendPQExpBufferStr(query,
                               8318                 :                :                          "SELECT c.tableoid, c.oid, "
                               8319                 :                :                          "conrelid, conname, confrelid, ");
                               8320         [ +  - ]:            189 :     if (fout->remoteVersion >= 110000)
                               8321                 :            189 :         appendPQExpBufferStr(query, "conindid, ");
                               8322                 :                :     else
 1421 tgl@sss.pgh.pa.us        8323                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS conindid, ");
 1421 tgl@sss.pgh.pa.us        8324                 :CBC         189 :     appendPQExpBuffer(query,
                               8325                 :                :                       "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
                               8326                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8327                 :                :                       "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               8328                 :                :                       "WHERE contype = 'f' ",
                               8329                 :                :                       tbloids->data);
                               8330         [ +  - ]:            189 :     if (fout->remoteVersion >= 110000)
                               8331                 :            189 :         appendPQExpBufferStr(query,
                               8332                 :                :                              "AND conparentid = 0 ");
                               8333                 :            189 :     appendPQExpBufferStr(query,
                               8334                 :                :                          "ORDER BY conrelid, conname");
                               8335                 :                : 
                               8336                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8337                 :                : 
                               8338                 :            189 :     ntups = PQntuples(res);
                               8339                 :                : 
                               8340                 :            189 :     i_contableoid = PQfnumber(res, "tableoid");
                               8341                 :            189 :     i_conoid = PQfnumber(res, "oid");
                               8342                 :            189 :     i_conrelid = PQfnumber(res, "conrelid");
                               8343                 :            189 :     i_conname = PQfnumber(res, "conname");
                               8344                 :            189 :     i_confrelid = PQfnumber(res, "confrelid");
                               8345                 :            189 :     i_conindid = PQfnumber(res, "conindid");
                               8346                 :            189 :     i_condef = PQfnumber(res, "condef");
                               8347                 :                : 
                               8348                 :            189 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
                               8349                 :                : 
                               8350                 :            189 :     curtblindx = -1;
                               8351         [ +  + ]:            360 :     for (int j = 0; j < ntups; j++)
                               8352                 :                :     {
                               8353                 :            171 :         Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               8354                 :                :         TableInfo  *reftable;
                               8355                 :                : 
                               8356                 :                :         /*
                               8357                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8358                 :                :          * order.
                               8359                 :                :          */
                               8360   [ +  +  +  + ]:            171 :         if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
                               8361                 :                :         {
                               8362         [ +  - ]:          13533 :             while (++curtblindx < numTables)
                               8363                 :                :             {
                               8364                 :          13533 :                 tbinfo = &tblinfo[curtblindx];
                               8365         [ +  + ]:          13533 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               8366                 :            161 :                     break;
                               8367                 :                :             }
                               8368         [ -  + ]:            161 :             if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        8369                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               8370                 :                :         }
                               8371                 :                : 
 1421 tgl@sss.pgh.pa.us        8372                 :CBC         171 :         constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
                               8373                 :            171 :         constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               8374                 :            171 :         constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               8375                 :            171 :         AssignDumpId(&constrinfo[j].dobj);
                               8376                 :            171 :         constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               8377                 :            171 :         constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               8378                 :            171 :         constrinfo[j].contable = tbinfo;
                               8379                 :            171 :         constrinfo[j].condomain = NULL;
                               8380                 :            171 :         constrinfo[j].contype = 'f';
                               8381                 :            171 :         constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               8382                 :            171 :         constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
                               8383                 :            171 :         constrinfo[j].conindex = 0;
                               8384                 :            171 :         constrinfo[j].condeferrable = false;
                               8385                 :            171 :         constrinfo[j].condeferred = false;
                               8386                 :            171 :         constrinfo[j].conislocal = true;
                               8387                 :            171 :         constrinfo[j].separate = true;
                               8388                 :                : 
                               8389                 :                :         /*
                               8390                 :                :          * Restoring an FK that points to a partitioned table requires that
                               8391                 :                :          * all partition indexes have been attached beforehand. Ensure that
                               8392                 :                :          * happens by making the constraint depend on each index partition
                               8393                 :                :          * attach object.
                               8394                 :                :          */
                               8395                 :            171 :         reftable = findTableByOid(constrinfo[j].confrelid);
                               8396   [ +  -  +  + ]:            171 :         if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
                               8397                 :                :         {
                               8398                 :             20 :             Oid         indexOid = atooid(PQgetvalue(res, j, i_conindid));
                               8399                 :                : 
                               8400         [ +  - ]:             20 :             if (indexOid != InvalidOid)
                               8401                 :                :             {
                               8402         [ +  - ]:             20 :                 for (int k = 0; k < reftable->numIndexes; k++)
                               8403                 :                :                 {
                               8404                 :                :                     IndxInfo   *refidx;
                               8405                 :                : 
                               8406                 :                :                     /* not our index? */
                               8407         [ -  + ]:             20 :                     if (reftable->indexes[k].dobj.catId.oid != indexOid)
 1421 tgl@sss.pgh.pa.us        8408                 :UBC           0 :                         continue;
                               8409                 :                : 
 1421 tgl@sss.pgh.pa.us        8410                 :CBC          20 :                     refidx = &reftable->indexes[k];
                               8411                 :             20 :                     addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
                               8412                 :             20 :                     break;
                               8413                 :                :                 }
                               8414                 :                :             }
                               8415                 :                :         }
                               8416                 :                :     }
                               8417                 :                : 
                               8418                 :            189 :     PQclear(res);
                               8419                 :                : 
 7996                          8420                 :            189 :     destroyPQExpBuffer(query);
 1421                          8421                 :            189 :     destroyPQExpBuffer(tbloids);
 7996                          8422                 :            189 : }
                               8423                 :                : 
                               8424                 :                : /*
                               8425                 :                :  * addConstrChildIdxDeps
                               8426                 :                :  *
                               8427                 :                :  * Recursive subroutine for getConstraints
                               8428                 :                :  *
                               8429                 :                :  * Given an object representing a foreign key constraint and an index on the
                               8430                 :                :  * partitioned table it references, mark the constraint object as dependent
                               8431                 :                :  * on the DO_INDEX_ATTACH object of each index partition, recursively
                               8432                 :                :  * drilling down to their partitions if any.  This ensures that the FK is not
                               8433                 :                :  * restored until the index is fully marked valid.
                               8434                 :                :  */
                               8435                 :                : static void
 1720 peter@eisentraut.org     8436                 :             45 : addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
                               8437                 :                : {
                               8438                 :                :     SimplePtrListCell *cell;
                               8439                 :                : 
 1900 alvherre@alvh.no-ip.     8440         [ -  + ]:             45 :     Assert(dobj->objType == DO_FK_CONSTRAINT);
                               8441                 :                : 
                               8442         [ +  + ]:            155 :     for (cell = refidx->partattaches.head; cell; cell = cell->next)
                               8443                 :                :     {
                               8444                 :            110 :         IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
                               8445                 :                : 
                               8446                 :            110 :         addObjectDependency(dobj, attach->dobj.dumpId);
                               8447                 :                : 
                               8448         [ +  + ]:            110 :         if (attach->partitionIdx->partattaches.head != NULL)
                               8449                 :             25 :             addConstrChildIdxDeps(dobj, attach->partitionIdx);
                               8450                 :                :     }
                               8451                 :             45 : }
                               8452                 :                : 
                               8453                 :                : /*
                               8454                 :                :  * getDomainConstraints
                               8455                 :                :  *
                               8456                 :                :  * Get info about constraints on a domain.
                               8457                 :                :  */
                               8458                 :                : static void
 5012 rhaas@postgresql.org     8459                 :            158 : getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
                               8460                 :                : {
                               8461                 :                :     ConstraintInfo *constrinfo;
 1421 tgl@sss.pgh.pa.us        8462                 :            158 :     PQExpBuffer query = createPQExpBuffer();
                               8463                 :                :     PGresult   *res;
                               8464                 :                :     int         i_tableoid,
                               8465                 :                :                 i_oid,
                               8466                 :                :                 i_conname,
                               8467                 :                :                 i_consrc,
                               8468                 :                :                 i_convalidated,
                               8469                 :                :                 i_contype;
                               8470                 :                :     int         ntups;
                               8471                 :                : 
                               8472         [ +  + ]:            158 :     if (!fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS])
                               8473                 :                :     {
                               8474                 :                :         /*
                               8475                 :                :          * Set up query for constraint-specific details.  For servers 17 and
                               8476                 :                :          * up, domains have constraints of type 'n' as well as 'c', otherwise
                               8477                 :                :          * just the latter.
                               8478                 :                :          */
   98 alvherre@kurilemu.de     8479                 :             43 :         appendPQExpBuffer(query,
                               8480                 :                :                           "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
                               8481                 :                :                           "SELECT tableoid, oid, conname, "
                               8482                 :                :                           "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
                               8483                 :                :                           "convalidated, contype "
                               8484                 :                :                           "FROM pg_catalog.pg_constraint "
                               8485                 :                :                           "WHERE contypid = $1 AND contype IN (%s) "
                               8486                 :                :                           "ORDER BY conname",
                               8487         [ -  + ]:             43 :                           fout->remoteVersion < 170000 ? "'c'" : "'c', 'n'");
                               8488                 :                : 
 1421 tgl@sss.pgh.pa.us        8489                 :             43 :         ExecuteSqlStatement(fout, query->data);
                               8490                 :                : 
                               8491                 :             43 :         fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS] = true;
                               8492                 :                :     }
                               8493                 :                : 
                               8494                 :            158 :     printfPQExpBuffer(query,
                               8495                 :                :                       "EXECUTE getDomainConstraints('%u')",
                               8496                 :                :                       tyinfo->dobj.catId.oid);
                               8497                 :                : 
 5011 rhaas@postgresql.org     8498                 :            158 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8499                 :                : 
 7996 tgl@sss.pgh.pa.us        8500                 :            158 :     ntups = PQntuples(res);
                               8501                 :                : 
                               8502                 :            158 :     i_tableoid = PQfnumber(res, "tableoid");
                               8503                 :            158 :     i_oid = PQfnumber(res, "oid");
                               8504                 :            158 :     i_conname = PQfnumber(res, "conname");
                               8505                 :            158 :     i_consrc = PQfnumber(res, "consrc");
   98 alvherre@kurilemu.de     8506                 :            158 :     i_convalidated = PQfnumber(res, "convalidated");
                               8507                 :            158 :     i_contype = PQfnumber(res, "contype");
                               8508                 :                : 
 5085 bruce@momjian.us         8509                 :            158 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 5787                          8510                 :            158 :     tyinfo->domChecks = constrinfo;
                               8511                 :                : 
                               8512                 :                :     /* 'i' tracks result rows; 'j' counts CHECK constraints */
   98 alvherre@kurilemu.de     8513         [ +  + ]:            324 :     for (int i = 0, j = 0; i < ntups; i++)
                               8514                 :                :     {
                               8515                 :            166 :         bool        validated = PQgetvalue(res, i, i_convalidated)[0] == 't';
                               8516                 :            166 :         char        contype = (PQgetvalue(res, i, i_contype))[0];
                               8517                 :                :         ConstraintInfo *constraint;
                               8518                 :                : 
                               8519         [ +  + ]:            166 :         if (contype == CONSTRAINT_CHECK)
                               8520                 :                :         {
                               8521                 :            113 :             constraint = &constrinfo[j++];
                               8522                 :            113 :             tyinfo->nDomChecks++;
                               8523                 :                :         }
                               8524                 :                :         else
                               8525                 :                :         {
                               8526         [ -  + ]:             53 :             Assert(contype == CONSTRAINT_NOTNULL);
                               8527         [ -  + ]:             53 :             Assert(tyinfo->notnull == NULL);
                               8528                 :                :             /* use last item in array for the not-null constraint */
                               8529                 :             53 :             tyinfo->notnull = &(constrinfo[ntups - 1]);
                               8530                 :             53 :             constraint = tyinfo->notnull;
                               8531                 :                :         }
                               8532                 :                : 
                               8533                 :            166 :         constraint->dobj.objType = DO_CONSTRAINT;
                               8534                 :            166 :         constraint->dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8535                 :            166 :         constraint->dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8536                 :            166 :         AssignDumpId(&(constraint->dobj));
                               8537                 :            166 :         constraint->dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
                               8538                 :            166 :         constraint->dobj.namespace = tyinfo->dobj.namespace;
                               8539                 :            166 :         constraint->contable = NULL;
                               8540                 :            166 :         constraint->condomain = tyinfo;
                               8541                 :            166 :         constraint->contype = contype;
                               8542                 :            166 :         constraint->condef = pg_strdup(PQgetvalue(res, i, i_consrc));
                               8543                 :            166 :         constraint->confrelid = InvalidOid;
                               8544                 :            166 :         constraint->conindex = 0;
                               8545                 :            166 :         constraint->condeferrable = false;
                               8546                 :            166 :         constraint->condeferred = false;
                               8547                 :            166 :         constraint->conislocal = true;
                               8548                 :                : 
                               8549                 :            166 :         constraint->separate = !validated;
                               8550                 :                : 
                               8551                 :                :         /*
                               8552                 :                :          * Make the domain depend on the constraint, ensuring it won't be
                               8553                 :                :          * output till any constraint dependencies are OK.  If the constraint
                               8554                 :                :          * has not been validated, it's going to be dumped after the domain
                               8555                 :                :          * anyway, so this doesn't matter.
                               8556                 :                :          */
 5085 alvherre@alvh.no-ip.     8557         [ +  + ]:            166 :         if (validated)
   98 alvherre@kurilemu.de     8558                 :            161 :             addObjectDependency(&tyinfo->dobj, constraint->dobj.dumpId);
                               8559                 :                :     }
                               8560                 :                : 
 7996 tgl@sss.pgh.pa.us        8561                 :            158 :     PQclear(res);
                               8562                 :                : 
                               8563                 :            158 :     destroyPQExpBuffer(query);
                               8564                 :            158 : }
                               8565                 :                : 
                               8566                 :                : /*
                               8567                 :                :  * getRules
                               8568                 :                :  *    get basic information about every rule in the system
                               8569                 :                :  */
                               8570                 :                : void
  482 nathan@postgresql.or     8571                 :            189 : getRules(Archive *fout)
                               8572                 :                : {
                               8573                 :                :     PGresult   *res;
                               8574                 :                :     int         ntups;
                               8575                 :                :     int         i;
 7996 tgl@sss.pgh.pa.us        8576                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               8577                 :                :     RuleInfo   *ruleinfo;
                               8578                 :                :     int         i_tableoid;
                               8579                 :                :     int         i_oid;
                               8580                 :                :     int         i_rulename;
                               8581                 :                :     int         i_ruletable;
                               8582                 :                :     int         i_ev_type;
                               8583                 :                :     int         i_is_instead;
                               8584                 :                :     int         i_ev_enabled;
                               8585                 :                : 
 1413                          8586                 :            189 :     appendPQExpBufferStr(query, "SELECT "
                               8587                 :                :                          "tableoid, oid, rulename, "
                               8588                 :                :                          "ev_class AS ruletable, ev_type, is_instead, "
                               8589                 :                :                          "ev_enabled "
                               8590                 :                :                          "FROM pg_rewrite "
                               8591                 :                :                          "ORDER BY oid");
                               8592                 :                : 
 5011 rhaas@postgresql.org     8593                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8594                 :                : 
 7996 tgl@sss.pgh.pa.us        8595                 :            189 :     ntups = PQntuples(res);
                               8596                 :                : 
 5085 bruce@momjian.us         8597                 :            189 :     ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
                               8598                 :                : 
 7996 tgl@sss.pgh.pa.us        8599                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8600                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8601                 :            189 :     i_rulename = PQfnumber(res, "rulename");
                               8602                 :            189 :     i_ruletable = PQfnumber(res, "ruletable");
                               8603                 :            189 :     i_ev_type = PQfnumber(res, "ev_type");
                               8604                 :            189 :     i_is_instead = PQfnumber(res, "is_instead");
 6797 JanWieck@Yahoo.com       8605                 :            189 :     i_ev_enabled = PQfnumber(res, "ev_enabled");
                               8606                 :                : 
 7996 tgl@sss.pgh.pa.us        8607         [ +  + ]:          29496 :     for (i = 0; i < ntups; i++)
                               8608                 :                :     {
                               8609                 :                :         Oid         ruletableoid;
                               8610                 :                : 
                               8611                 :          29307 :         ruleinfo[i].dobj.objType = DO_RULE;
                               8612                 :          29307 :         ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8613                 :          29307 :         ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8614                 :          29307 :         AssignDumpId(&ruleinfo[i].dobj);
 5085 bruce@momjian.us         8615                 :          29307 :         ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
 7996 tgl@sss.pgh.pa.us        8616                 :          29307 :         ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                               8617                 :          29307 :         ruleinfo[i].ruletable = findTableByOid(ruletableoid);
 7532                          8618         [ -  + ]:          29307 :         if (ruleinfo[i].ruletable == NULL)
 1298 tgl@sss.pgh.pa.us        8619                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
                               8620                 :                :                      ruletableoid, ruleinfo[i].dobj.catId.oid);
 7908 tgl@sss.pgh.pa.us        8621                 :CBC       29307 :         ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
 7179                          8622                 :          29307 :         ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
 7996                          8623                 :          29307 :         ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
                               8624                 :          29307 :         ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
 6797 JanWieck@Yahoo.com       8625                 :          29307 :         ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
 7996 tgl@sss.pgh.pa.us        8626         [ +  - ]:          29307 :         if (ruleinfo[i].ruletable)
                               8627                 :                :         {
                               8628                 :                :             /*
                               8629                 :                :              * If the table is a view or materialized view, force its ON
                               8630                 :                :              * SELECT rule to be sorted before the view itself --- this
                               8631                 :                :              * ensures that any dependencies for the rule affect the table's
                               8632                 :                :              * positioning. Other rules are forced to appear after their
                               8633                 :                :              * table.
                               8634                 :                :              */
 4621 kgrittn@postgresql.o     8635         [ +  + ]:          29307 :             if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
 4600 andrew@dunslane.net      8636         [ +  + ]:            702 :                  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
 7996 tgl@sss.pgh.pa.us        8637   [ +  +  +  - ]:          29076 :                 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
                               8638                 :                :             {
                               8639                 :          28656 :                 addObjectDependency(&ruleinfo[i].ruletable->dobj,
                               8640                 :          28656 :                                     ruleinfo[i].dobj.dumpId);
                               8641                 :                :                 /* We'll merge the rule into CREATE VIEW, if possible */
 7622                          8642                 :          28656 :                 ruleinfo[i].separate = false;
                               8643                 :                :             }
                               8644                 :                :             else
                               8645                 :                :             {
 7996                          8646                 :            651 :                 addObjectDependency(&ruleinfo[i].dobj,
                               8647                 :            651 :                                     ruleinfo[i].ruletable->dobj.dumpId);
 7622                          8648                 :            651 :                 ruleinfo[i].separate = true;
                               8649                 :                :             }
                               8650                 :                :         }
                               8651                 :                :         else
 7622 tgl@sss.pgh.pa.us        8652                 :UBC           0 :             ruleinfo[i].separate = true;
                               8653                 :                :     }
                               8654                 :                : 
 7996 tgl@sss.pgh.pa.us        8655                 :CBC         189 :     PQclear(res);
                               8656                 :                : 
                               8657                 :            189 :     destroyPQExpBuffer(query);
                               8658                 :            189 : }
                               8659                 :                : 
                               8660                 :                : /*
                               8661                 :                :  * getTriggers
                               8662                 :                :  *    get information about every trigger on a dumpable table
                               8663                 :                :  *
                               8664                 :                :  * Note: trigger data is not returned directly to the caller, but it
                               8665                 :                :  * does get entered into the DumpableObject tables.
                               8666                 :                :  */
                               8667                 :                : void
 5012 rhaas@postgresql.org     8668                 :            189 : getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                               8669                 :                : {
 7996 tgl@sss.pgh.pa.us        8670                 :            189 :     PQExpBuffer query = createPQExpBuffer();
 1421                          8671                 :            189 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8672                 :                :     PGresult   *res;
                               8673                 :                :     int         ntups;
                               8674                 :                :     int         curtblindx;
                               8675                 :                :     TriggerInfo *tginfo;
                               8676                 :                :     int         i_tableoid,
                               8677                 :                :                 i_oid,
                               8678                 :                :                 i_tgrelid,
                               8679                 :                :                 i_tgname,
                               8680                 :                :                 i_tgenabled,
                               8681                 :                :                 i_tgispartition,
                               8682                 :                :                 i_tgdef;
                               8683                 :                : 
                               8684                 :                :     /*
                               8685                 :                :      * We want to perform just one query against pg_trigger.  However, we
                               8686                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               8687                 :                :      * the client side, because some of the server-side functions we need
                               8688                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8689                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8690                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8691                 :                :      */
                               8692                 :            189 :     appendPQExpBufferChar(tbloids, '{');
                               8693         [ +  + ]:          49831 :     for (int i = 0; i < numTables; i++)
                               8694                 :                :     {
 7996                          8695                 :          49642 :         TableInfo  *tbinfo = &tblinfo[i];
                               8696                 :                : 
 3491 sfrost@snowman.net       8697         [ +  + ]:          49642 :         if (!tbinfo->hastriggers ||
                               8698         [ +  + ]:           1114 :             !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7996 tgl@sss.pgh.pa.us        8699                 :          48790 :             continue;
                               8700                 :                : 
                               8701                 :                :         /* OK, we need info for this table */
 1421                          8702         [ +  + ]:            852 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8703                 :            801 :             appendPQExpBufferChar(tbloids, ',');
                               8704                 :            852 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               8705                 :                :     }
                               8706                 :            189 :     appendPQExpBufferChar(tbloids, '}');
                               8707                 :                : 
 1391 alvherre@alvh.no-ip.     8708         [ +  - ]:            189 :     if (fout->remoteVersion >= 150000)
                               8709                 :                :     {
                               8710                 :                :         /*
                               8711                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8712                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8713                 :                :          * under-parenthesization.
                               8714                 :                :          *
                               8715                 :                :          * NB: We need to see partition triggers in case the tgenabled flag
                               8716                 :                :          * has been changed from the parent.
                               8717                 :                :          */
                               8718                 :            189 :         appendPQExpBuffer(query,
                               8719                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8720                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8721                 :                :                           "t.tgenabled, t.tableoid, t.oid, "
                               8722                 :                :                           "t.tgparentid <> 0 AS tgispartition\n"
                               8723                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8724                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8725                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8726                 :                :                           "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
                               8727                 :                :                           "OR t.tgenabled != u.tgenabled) "
                               8728                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8729                 :                :                           tbloids->data);
                               8730                 :                :     }
 1391 alvherre@alvh.no-ip.     8731         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 130000)
                               8732                 :                :     {
                               8733                 :                :         /*
                               8734                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8735                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8736                 :                :          * under-parenthesization.
                               8737                 :                :          *
                               8738                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8739                 :                :          * tgenabled flag has been changed from the parent.
                               8740                 :                :          */
 1421 tgl@sss.pgh.pa.us        8741                 :              0 :         appendPQExpBuffer(query,
                               8742                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8743                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8744                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
                               8745                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8746                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8747                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8748                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
                               8749                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8750                 :                :                           tbloids->data);
                               8751                 :                :     }
                               8752         [ #  # ]:              0 :     else if (fout->remoteVersion >= 110000)
                               8753                 :                :     {
                               8754                 :                :         /*
                               8755                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8756                 :                :          * tgenabled flag has been changed from the parent. No tgparentid in
                               8757                 :                :          * version 11-12, so we have to match them via pg_depend.
                               8758                 :                :          *
                               8759                 :                :          * See above about pretty=true in pg_get_triggerdef.
                               8760                 :                :          */
                               8761                 :              0 :         appendPQExpBuffer(query,
                               8762                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8763                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8764                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
                               8765                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8766                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8767                 :                :                           "LEFT JOIN pg_catalog.pg_depend AS d ON "
                               8768                 :                :                           " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8769                 :                :                           " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8770                 :                :                           " d.objid = t.oid "
                               8771                 :                :                           "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
                               8772                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
                               8773                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8774                 :                :                           tbloids->data);
                               8775                 :                :     }
                               8776                 :                :     else
                               8777                 :                :     {
                               8778                 :                :         /* See above about pretty=true in pg_get_triggerdef */
                               8779                 :              0 :         appendPQExpBuffer(query,
                               8780                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8781                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8782                 :                :                           "t.tgenabled, false as tgispartition, "
                               8783                 :                :                           "t.tableoid, t.oid "
                               8784                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8785                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8786                 :                :                           "WHERE NOT tgisinternal "
                               8787                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8788                 :                :                           tbloids->data);
                               8789                 :                :     }
                               8790                 :                : 
 1421 tgl@sss.pgh.pa.us        8791                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8792                 :                : 
                               8793                 :            189 :     ntups = PQntuples(res);
                               8794                 :                : 
                               8795                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8796                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8797                 :            189 :     i_tgrelid = PQfnumber(res, "tgrelid");
                               8798                 :            189 :     i_tgname = PQfnumber(res, "tgname");
                               8799                 :            189 :     i_tgenabled = PQfnumber(res, "tgenabled");
 1391 alvherre@alvh.no-ip.     8800                 :            189 :     i_tgispartition = PQfnumber(res, "tgispartition");
 1421 tgl@sss.pgh.pa.us        8801                 :            189 :     i_tgdef = PQfnumber(res, "tgdef");
                               8802                 :                : 
                               8803                 :            189 :     tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
                               8804                 :                : 
                               8805                 :                :     /*
                               8806                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               8807                 :                :      * j is handled by the inner loop.
                               8808                 :                :      */
                               8809                 :            189 :     curtblindx = -1;
                               8810         [ +  + ]:            495 :     for (int j = 0; j < ntups;)
                               8811                 :                :     {
                               8812                 :            306 :         Oid         tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
                               8813                 :            306 :         TableInfo  *tbinfo = NULL;
                               8814                 :                :         int         numtrigs;
                               8815                 :                : 
                               8816                 :                :         /* Count rows for this table */
                               8817         [ +  + ]:            523 :         for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
                               8818         [ +  + ]:            472 :             if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
                               8819                 :            255 :                 break;
                               8820                 :                : 
                               8821                 :                :         /*
                               8822                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8823                 :                :          * order.
                               8824                 :                :          */
                               8825         [ +  - ]:          16042 :         while (++curtblindx < numTables)
                               8826                 :                :         {
                               8827                 :          16042 :             tbinfo = &tblinfo[curtblindx];
                               8828         [ +  + ]:          16042 :             if (tbinfo->dobj.catId.oid == tgrelid)
                               8829                 :            306 :                 break;
                               8830                 :                :         }
                               8831         [ -  + ]:            306 :         if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        8832                 :UBC           0 :             pg_fatal("unrecognized table OID %u", tgrelid);
                               8833                 :                : 
                               8834                 :                :         /* Save data for this table */
 1421 tgl@sss.pgh.pa.us        8835                 :CBC         306 :         tbinfo->triggers = tginfo + j;
                               8836                 :            306 :         tbinfo->numTriggers = numtrigs;
                               8837                 :                : 
                               8838         [ +  + ]:            829 :         for (int c = 0; c < numtrigs; c++, j++)
                               8839                 :                :         {
 7996                          8840                 :            523 :             tginfo[j].dobj.objType = DO_TRIGGER;
                               8841                 :            523 :             tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               8842                 :            523 :             tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               8843                 :            523 :             AssignDumpId(&tginfo[j].dobj);
 5085 bruce@momjian.us         8844                 :            523 :             tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
 7908 tgl@sss.pgh.pa.us        8845                 :            523 :             tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7996                          8846                 :            523 :             tginfo[j].tgtable = tbinfo;
 6797 JanWieck@Yahoo.com       8847                 :            523 :             tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
 1391 alvherre@alvh.no-ip.     8848                 :            523 :             tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
  652 peter@eisentraut.org     8849                 :            523 :             tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
                               8850                 :                :         }
                               8851                 :                :     }
                               8852                 :                : 
 1421 tgl@sss.pgh.pa.us        8853                 :            189 :     PQclear(res);
                               8854                 :                : 
 7996                          8855                 :            189 :     destroyPQExpBuffer(query);
 1421                          8856                 :            189 :     destroyPQExpBuffer(tbloids);
 7996                          8857                 :            189 : }
                               8858                 :                : 
                               8859                 :                : /*
                               8860                 :                :  * getEventTriggers
                               8861                 :                :  *    get information about event triggers
                               8862                 :                :  */
                               8863                 :                : void
  482 nathan@postgresql.or     8864                 :            189 : getEventTriggers(Archive *fout)
                               8865                 :                : {
                               8866                 :                :     int         i;
                               8867                 :                :     PQExpBuffer query;
                               8868                 :                :     PGresult   *res;
                               8869                 :                :     EventTriggerInfo *evtinfo;
                               8870                 :                :     int         i_tableoid,
                               8871                 :                :                 i_oid,
                               8872                 :                :                 i_evtname,
                               8873                 :                :                 i_evtevent,
                               8874                 :                :                 i_evtowner,
                               8875                 :                :                 i_evttags,
                               8876                 :                :                 i_evtfname,
                               8877                 :                :                 i_evtenabled;
                               8878                 :                :     int         ntups;
                               8879                 :                : 
                               8880                 :                :     /* Before 9.3, there are no event triggers */
 4849 rhaas@postgresql.org     8881         [ -  + ]:            189 :     if (fout->remoteVersion < 90300)
  482 nathan@postgresql.or     8882                 :UBC           0 :         return;
                               8883                 :                : 
 4488 sfrost@snowman.net       8884                 :CBC         189 :     query = createPQExpBuffer();
                               8885                 :                : 
 1147 drowley@postgresql.o     8886                 :            189 :     appendPQExpBufferStr(query,
                               8887                 :                :                          "SELECT e.tableoid, e.oid, evtname, evtenabled, "
                               8888                 :                :                          "evtevent, evtowner, "
                               8889                 :                :                          "array_to_string(array("
                               8890                 :                :                          "select quote_literal(x) "
                               8891                 :                :                          " from unnest(evttags) as t(x)), ', ') as evttags, "
                               8892                 :                :                          "e.evtfoid::regproc as evtfname "
                               8893                 :                :                          "FROM pg_event_trigger e "
                               8894                 :                :                          "ORDER BY e.oid");
                               8895                 :                : 
 4849 rhaas@postgresql.org     8896                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8897                 :                : 
                               8898                 :            189 :     ntups = PQntuples(res);
                               8899                 :                : 
                               8900                 :            189 :     evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
                               8901                 :                : 
                               8902                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8903                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8904                 :            189 :     i_evtname = PQfnumber(res, "evtname");
                               8905                 :            189 :     i_evtevent = PQfnumber(res, "evtevent");
                               8906                 :            189 :     i_evtowner = PQfnumber(res, "evtowner");
                               8907                 :            189 :     i_evttags = PQfnumber(res, "evttags");
                               8908                 :            189 :     i_evtfname = PQfnumber(res, "evtfname");
                               8909                 :            189 :     i_evtenabled = PQfnumber(res, "evtenabled");
                               8910                 :                : 
                               8911         [ +  + ]:            241 :     for (i = 0; i < ntups; i++)
                               8912                 :                :     {
                               8913                 :             52 :         evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
                               8914                 :             52 :         evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8915                 :             52 :         evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8916                 :             52 :         AssignDumpId(&evtinfo[i].dobj);
                               8917                 :             52 :         evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8918                 :             52 :         evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8919                 :             52 :         evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
 1396 tgl@sss.pgh.pa.us        8920                 :             52 :         evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
 4849 rhaas@postgresql.org     8921                 :             52 :         evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
                               8922                 :             52 :         evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
                               8923                 :             52 :         evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
                               8924                 :                : 
                               8925                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       8926                 :             52 :         selectDumpableObject(&(evtinfo[i].dobj), fout);
                               8927                 :                :     }
                               8928                 :                : 
 4849 rhaas@postgresql.org     8929                 :            189 :     PQclear(res);
                               8930                 :                : 
                               8931                 :            189 :     destroyPQExpBuffer(query);
                               8932                 :                : }
                               8933                 :                : 
                               8934                 :                : /*
                               8935                 :                :  * getProcLangs
                               8936                 :                :  *    get basic information about every procedural language in the system
                               8937                 :                :  *
                               8938                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               8939                 :                :  * findFuncByOid().
                               8940                 :                :  */
                               8941                 :                : void
  482 nathan@postgresql.or     8942                 :            189 : getProcLangs(Archive *fout)
                               8943                 :                : {
                               8944                 :                :     PGresult   *res;
                               8945                 :                :     int         ntups;
                               8946                 :                :     int         i;
 7996 tgl@sss.pgh.pa.us        8947                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               8948                 :                :     ProcLangInfo *planginfo;
                               8949                 :                :     int         i_tableoid;
                               8950                 :                :     int         i_oid;
                               8951                 :                :     int         i_lanname;
                               8952                 :                :     int         i_lanpltrusted;
                               8953                 :                :     int         i_lanplcallfoid;
                               8954                 :                :     int         i_laninline;
                               8955                 :                :     int         i_lanvalidator;
                               8956                 :                :     int         i_lanacl;
                               8957                 :                :     int         i_acldefault;
                               8958                 :                :     int         i_lanowner;
                               8959                 :                : 
 1147 drowley@postgresql.o     8960                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8961                 :                :                          "lanname, lanpltrusted, lanplcallfoid, "
                               8962                 :                :                          "laninline, lanvalidator, "
                               8963                 :                :                          "lanacl, "
                               8964                 :                :                          "acldefault('l', lanowner) AS acldefault, "
                               8965                 :                :                          "lanowner "
                               8966                 :                :                          "FROM pg_language "
                               8967                 :                :                          "WHERE lanispl "
                               8968                 :                :                          "ORDER BY oid");
                               8969                 :                : 
 5011 rhaas@postgresql.org     8970                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8971                 :                : 
 7996 tgl@sss.pgh.pa.us        8972                 :            189 :     ntups = PQntuples(res);
                               8973                 :                : 
 5085 bruce@momjian.us         8974                 :            189 :     planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
                               8975                 :                : 
 7996 tgl@sss.pgh.pa.us        8976                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               8977                 :            189 :     i_oid = PQfnumber(res, "oid");
                               8978                 :            189 :     i_lanname = PQfnumber(res, "lanname");
                               8979                 :            189 :     i_lanpltrusted = PQfnumber(res, "lanpltrusted");
                               8980                 :            189 :     i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
 5879                          8981                 :            189 :     i_laninline = PQfnumber(res, "laninline");
 7268                          8982                 :            189 :     i_lanvalidator = PQfnumber(res, "lanvalidator");
                               8983                 :            189 :     i_lanacl = PQfnumber(res, "lanacl");
 1421                          8984                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
 7268                          8985                 :            189 :     i_lanowner = PQfnumber(res, "lanowner");
                               8986                 :                : 
 7996                          8987         [ +  + ]:            423 :     for (i = 0; i < ntups; i++)
                               8988                 :                :     {
                               8989                 :            234 :         planginfo[i].dobj.objType = DO_PROCLANG;
                               8990                 :            234 :         planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8991                 :            234 :         planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8992                 :            234 :         AssignDumpId(&planginfo[i].dobj);
                               8993                 :                : 
 5085 bruce@momjian.us         8994                 :            234 :         planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
 1421 tgl@sss.pgh.pa.us        8995                 :            234 :         planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
                               8996                 :            234 :         planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               8997                 :            234 :         planginfo[i].dacl.privtype = 0;
                               8998                 :            234 :         planginfo[i].dacl.initprivs = NULL;
 7996                          8999                 :            234 :         planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
                               9000                 :            234 :         planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
 3731                          9001                 :            234 :         planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
                               9002                 :            234 :         planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
 1396                          9003                 :            234 :         planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
                               9004                 :                : 
                               9005                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       9006                 :            234 :         selectDumpableProcLang(&(planginfo[i]), fout);
                               9007                 :                : 
                               9008                 :                :         /* Mark whether language has an ACL */
 1421 tgl@sss.pgh.pa.us        9009         [ +  + ]:            234 :         if (!PQgetisnull(res, i, i_lanacl))
                               9010                 :             45 :             planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               9011                 :                :     }
                               9012                 :                : 
 7996                          9013                 :            189 :     PQclear(res);
                               9014                 :                : 
                               9015                 :            189 :     destroyPQExpBuffer(query);
                               9016                 :            189 : }
                               9017                 :                : 
                               9018                 :                : /*
                               9019                 :                :  * getCasts
                               9020                 :                :  *    get basic information about most casts in the system
                               9021                 :                :  *
                               9022                 :                :  * Skip casts from a range to its multirange, since we'll create those
                               9023                 :                :  * automatically.
                               9024                 :                :  */
                               9025                 :                : void
  482 nathan@postgresql.or     9026                 :            189 : getCasts(Archive *fout)
                               9027                 :                : {
                               9028                 :                :     PGresult   *res;
                               9029                 :                :     int         ntups;
                               9030                 :                :     int         i;
 7996 tgl@sss.pgh.pa.us        9031                 :            189 :     PQExpBuffer query = createPQExpBuffer();
                               9032                 :                :     CastInfo   *castinfo;
                               9033                 :                :     int         i_tableoid;
                               9034                 :                :     int         i_oid;
                               9035                 :                :     int         i_castsource;
                               9036                 :                :     int         i_casttarget;
                               9037                 :                :     int         i_castfunc;
                               9038                 :                :     int         i_castcontext;
                               9039                 :                :     int         i_castmethod;
                               9040                 :                : 
 1772 akorotkov@postgresql     9041         [ +  - ]:            189 :     if (fout->remoteVersion >= 140000)
                               9042                 :                :     {
                               9043                 :            189 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               9044                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               9045                 :                :                              "castmethod "
                               9046                 :                :                              "FROM pg_cast c "
                               9047                 :                :                              "WHERE NOT EXISTS ( "
                               9048                 :                :                              "SELECT 1 FROM pg_range r "
                               9049                 :                :                              "WHERE c.castsource = r.rngtypid "
                               9050                 :                :                              "AND c.casttarget = r.rngmultitypid "
                               9051                 :                :                              ") "
                               9052                 :                :                              "ORDER BY 3,4");
                               9053                 :                :     }
                               9054                 :                :     else
                               9055                 :                :     {
 4361 heikki.linnakangas@i     9056                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               9057                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               9058                 :                :                              "castmethod "
                               9059                 :                :                              "FROM pg_cast ORDER BY 3,4");
                               9060                 :                :     }
                               9061                 :                : 
 5011 rhaas@postgresql.org     9062                 :CBC         189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9063                 :                : 
 7996 tgl@sss.pgh.pa.us        9064                 :            189 :     ntups = PQntuples(res);
                               9065                 :                : 
 5085 bruce@momjian.us         9066                 :            189 :     castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
                               9067                 :                : 
 7996 tgl@sss.pgh.pa.us        9068                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               9069                 :            189 :     i_oid = PQfnumber(res, "oid");
                               9070                 :            189 :     i_castsource = PQfnumber(res, "castsource");
                               9071                 :            189 :     i_casttarget = PQfnumber(res, "casttarget");
                               9072                 :            189 :     i_castfunc = PQfnumber(res, "castfunc");
                               9073                 :            189 :     i_castcontext = PQfnumber(res, "castcontext");
 6205 heikki.linnakangas@i     9074                 :            189 :     i_castmethod = PQfnumber(res, "castmethod");
                               9075                 :                : 
 7996 tgl@sss.pgh.pa.us        9076         [ +  + ]:          44880 :     for (i = 0; i < ntups; i++)
                               9077                 :                :     {
                               9078                 :                :         PQExpBufferData namebuf;
                               9079                 :                :         TypeInfo   *sTypeInfo;
                               9080                 :                :         TypeInfo   *tTypeInfo;
                               9081                 :                : 
                               9082                 :          44691 :         castinfo[i].dobj.objType = DO_CAST;
                               9083                 :          44691 :         castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9084                 :          44691 :         castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9085                 :          44691 :         AssignDumpId(&castinfo[i].dobj);
                               9086                 :          44691 :         castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
                               9087                 :          44691 :         castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
                               9088                 :          44691 :         castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
                               9089                 :          44691 :         castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
 6205 heikki.linnakangas@i     9090                 :          44691 :         castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
                               9091                 :                : 
                               9092                 :                :         /*
                               9093                 :                :          * Try to name cast as concatenation of typnames.  This is only used
                               9094                 :                :          * for purposes of sorting.  If we fail to find either type, the name
                               9095                 :                :          * will be an empty string.
                               9096                 :                :          */
 7908 tgl@sss.pgh.pa.us        9097                 :          44691 :         initPQExpBuffer(&namebuf);
                               9098                 :          44691 :         sTypeInfo = findTypeByOid(castinfo[i].castsource);
                               9099                 :          44691 :         tTypeInfo = findTypeByOid(castinfo[i].casttarget);
                               9100   [ +  -  +  - ]:          44691 :         if (sTypeInfo && tTypeInfo)
                               9101                 :          44691 :             appendPQExpBuffer(&namebuf, "%s %s",
                               9102                 :                :                               sTypeInfo->dobj.name, tTypeInfo->dobj.name);
                               9103                 :          44691 :         castinfo[i].dobj.name = namebuf.data;
                               9104                 :                : 
                               9105                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       9106                 :          44691 :         selectDumpableCast(&(castinfo[i]), fout);
                               9107                 :                :     }
                               9108                 :                : 
 7996 tgl@sss.pgh.pa.us        9109                 :            189 :     PQclear(res);
                               9110                 :                : 
                               9111                 :            189 :     destroyPQExpBuffer(query);
                               9112                 :            189 : }
                               9113                 :                : 
                               9114                 :                : static char *
 3837 peter_e@gmx.net          9115                 :             88 : get_language_name(Archive *fout, Oid langid)
                               9116                 :                : {
                               9117                 :                :     PQExpBuffer query;
                               9118                 :                :     PGresult   *res;
                               9119                 :                :     char       *lanname;
                               9120                 :                : 
                               9121                 :             88 :     query = createPQExpBuffer();
                               9122                 :             88 :     appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
                               9123                 :             88 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                               9124                 :             88 :     lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
                               9125                 :             88 :     destroyPQExpBuffer(query);
                               9126                 :             88 :     PQclear(res);
                               9127                 :                : 
                               9128                 :             88 :     return lanname;
                               9129                 :                : }
                               9130                 :                : 
                               9131                 :                : /*
                               9132                 :                :  * getTransforms
                               9133                 :                :  *    get basic information about every transform in the system
                               9134                 :                :  */
                               9135                 :                : void
  482 nathan@postgresql.or     9136                 :            189 : getTransforms(Archive *fout)
                               9137                 :                : {
                               9138                 :                :     PGresult   *res;
                               9139                 :                :     int         ntups;
                               9140                 :                :     int         i;
                               9141                 :                :     PQExpBuffer query;
                               9142                 :                :     TransformInfo *transforminfo;
                               9143                 :                :     int         i_tableoid;
                               9144                 :                :     int         i_oid;
                               9145                 :                :     int         i_trftype;
                               9146                 :                :     int         i_trflang;
                               9147                 :                :     int         i_trffromsql;
                               9148                 :                :     int         i_trftosql;
                               9149                 :                : 
                               9150                 :                :     /* Transforms didn't exist pre-9.5 */
 3837 peter_e@gmx.net          9151         [ -  + ]:            189 :     if (fout->remoteVersion < 90500)
  482 nathan@postgresql.or     9152                 :UBC           0 :         return;
                               9153                 :                : 
 3826 magnus@hagander.net      9154                 :CBC         189 :     query = createPQExpBuffer();
                               9155                 :                : 
 2307 drowley@postgresql.o     9156                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               9157                 :                :                          "trftype, trflang, trffromsql::oid, trftosql::oid "
                               9158                 :                :                          "FROM pg_transform "
                               9159                 :                :                          "ORDER BY 3,4");
                               9160                 :                : 
 3837 peter_e@gmx.net          9161                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9162                 :                : 
                               9163                 :            189 :     ntups = PQntuples(res);
                               9164                 :                : 
                               9165                 :            189 :     transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
                               9166                 :                : 
                               9167                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                               9168                 :            189 :     i_oid = PQfnumber(res, "oid");
                               9169                 :            189 :     i_trftype = PQfnumber(res, "trftype");
                               9170                 :            189 :     i_trflang = PQfnumber(res, "trflang");
                               9171                 :            189 :     i_trffromsql = PQfnumber(res, "trffromsql");
                               9172                 :            189 :     i_trftosql = PQfnumber(res, "trftosql");
                               9173                 :                : 
                               9174         [ +  + ]:            241 :     for (i = 0; i < ntups; i++)
                               9175                 :                :     {
                               9176                 :                :         PQExpBufferData namebuf;
                               9177                 :                :         TypeInfo   *typeInfo;
                               9178                 :                :         char       *lanname;
                               9179                 :                : 
                               9180                 :             52 :         transforminfo[i].dobj.objType = DO_TRANSFORM;
                               9181                 :             52 :         transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9182                 :             52 :         transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9183                 :             52 :         AssignDumpId(&transforminfo[i].dobj);
                               9184                 :             52 :         transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
                               9185                 :             52 :         transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
                               9186                 :             52 :         transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
                               9187                 :             52 :         transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
                               9188                 :                : 
                               9189                 :                :         /*
                               9190                 :                :          * Try to name transform as concatenation of type and language name.
                               9191                 :                :          * This is only used for purposes of sorting.  If we fail to find
                               9192                 :                :          * either, the name will be an empty string.
                               9193                 :                :          */
                               9194                 :             52 :         initPQExpBuffer(&namebuf);
                               9195                 :             52 :         typeInfo = findTypeByOid(transforminfo[i].trftype);
                               9196                 :             52 :         lanname = get_language_name(fout, transforminfo[i].trflang);
                               9197   [ +  -  +  - ]:             52 :         if (typeInfo && lanname)
                               9198                 :             52 :             appendPQExpBuffer(&namebuf, "%s %s",
                               9199                 :                :                               typeInfo->dobj.name, lanname);
                               9200                 :             52 :         transforminfo[i].dobj.name = namebuf.data;
 3760 tgl@sss.pgh.pa.us        9201                 :             52 :         free(lanname);
                               9202                 :                : 
                               9203                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net       9204                 :             52 :         selectDumpableObject(&(transforminfo[i].dobj), fout);
                               9205                 :                :     }
                               9206                 :                : 
 3837 peter_e@gmx.net          9207                 :            189 :     PQclear(res);
                               9208                 :                : 
                               9209                 :            189 :     destroyPQExpBuffer(query);
                               9210                 :                : }
                               9211                 :                : 
                               9212                 :                : /*
                               9213                 :                :  * getTableAttrs -
                               9214                 :                :  *    for each interesting table, read info about its attributes
                               9215                 :                :  *    (names, types, default values, CHECK constraints, etc)
                               9216                 :                :  *
                               9217                 :                :  *  modifies tblinfo
                               9218                 :                :  */
                               9219                 :                : void
 3575 tgl@sss.pgh.pa.us        9220                 :            189 : getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                               9221                 :                : {
                               9222                 :            189 :     DumpOptions *dopt = fout->dopt;
 7996                          9223                 :            189 :     PQExpBuffer q = createPQExpBuffer();
 1421                          9224                 :            189 :     PQExpBuffer tbloids = createPQExpBuffer();
                               9225                 :            189 :     PQExpBuffer checkoids = createPQExpBuffer();
  203 alvherre@alvh.no-ip.     9226                 :            189 :     PQExpBuffer invalidnotnulloids = NULL;
                               9227                 :                :     PGresult   *res;
                               9228                 :                :     int         ntups;
                               9229                 :                :     int         curtblindx;
                               9230                 :                :     int         i_attrelid;
                               9231                 :                :     int         i_attnum;
                               9232                 :                :     int         i_attname;
                               9233                 :                :     int         i_atttypname;
                               9234                 :                :     int         i_attstattarget;
                               9235                 :                :     int         i_attstorage;
                               9236                 :                :     int         i_typstorage;
                               9237                 :                :     int         i_attidentity;
                               9238                 :                :     int         i_attgenerated;
                               9239                 :                :     int         i_attisdropped;
                               9240                 :                :     int         i_attlen;
                               9241                 :                :     int         i_attalign;
                               9242                 :                :     int         i_attislocal;
                               9243                 :                :     int         i_notnull_name;
                               9244                 :                :     int         i_notnull_comment;
                               9245                 :                :     int         i_notnull_noinherit;
                               9246                 :                :     int         i_notnull_islocal;
                               9247                 :                :     int         i_notnull_invalidoid;
                               9248                 :                :     int         i_attoptions;
                               9249                 :                :     int         i_attcollation;
                               9250                 :                :     int         i_attcompression;
                               9251                 :                :     int         i_attfdwoptions;
                               9252                 :                :     int         i_attmissingval;
                               9253                 :                :     int         i_atthasdef;
                               9254                 :                : 
                               9255                 :                :     /*
                               9256                 :                :      * We want to perform just one query against pg_attribute, and then just
                               9257                 :                :      * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
                               9258                 :                :      * (for CHECK constraints and for NOT NULL constraints).  However, we
                               9259                 :                :      * mustn't try to select every row of those catalogs and then sort it out
                               9260                 :                :      * on the client side, because some of the server-side functions we need
                               9261                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               9262                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               9263                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               9264                 :                :      */
 1421 tgl@sss.pgh.pa.us        9265                 :            189 :     appendPQExpBufferChar(tbloids, '{');
                               9266                 :            189 :     appendPQExpBufferChar(checkoids, '{');
 1936 peter@eisentraut.org     9267         [ +  + ]:          49831 :     for (int i = 0; i < numTables; i++)
                               9268                 :                :     {
 8454 bruce@momjian.us         9269                 :          49642 :         TableInfo  *tbinfo = &tblinfo[i];
                               9270                 :                : 
                               9271                 :                :         /* Don't bother to collect info for sequences */
 8470 tgl@sss.pgh.pa.us        9272         [ +  + ]:          49642 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
10277 bruce@momjian.us         9273                 :            638 :             continue;
                               9274                 :                : 
                               9275                 :                :         /*
                               9276                 :                :          * Don't bother with uninteresting tables, either.  For binary
                               9277                 :                :          * upgrades, this is bypassed for pg_largeobject_metadata and
                               9278                 :                :          * pg_shdepend so that the columns names are collected for the
                               9279                 :                :          * corresponding COPY commands.  Restoring the data for those catalogs
                               9280                 :                :          * is faster than restoring the equivalent set of large object
                               9281                 :                :          * commands.  We can only do this for upgrades from v12 and newer; in
                               9282                 :                :          * older versions, pg_largeobject_metadata was created WITH OIDS, so
                               9283                 :                :          * the OID column is hidden and won't be dumped.
                               9284                 :                :          */
  101 nathan@postgresql.or     9285         [ +  + ]:GNC       49004 :         if (!tbinfo->interesting &&
                               9286   [ +  +  +  - ]:          42437 :             !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
                               9287         [ +  + ]:           7758 :               (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
                               9288         [ +  + ]:           7722 :                tbinfo->dobj.catId.oid == SharedDependRelationId)))
 8571 tgl@sss.pgh.pa.us        9289                 :CBC       42365 :             continue;
                               9290                 :                : 
                               9291                 :                :         /* OK, we need info for this table */
 1421                          9292         [ +  + ]:           6639 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               9293                 :           6494 :             appendPQExpBufferChar(tbloids, ',');
                               9294                 :           6639 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               9295                 :                : 
                               9296         [ +  + ]:           6639 :         if (tbinfo->ncheck > 0)
                               9297                 :                :         {
                               9298                 :                :             /* Also make a list of the ones with check constraints */
                               9299         [ +  + ]:            528 :             if (checkoids->len > 1) /* do we have more than the '{'? */
                               9300                 :            459 :                 appendPQExpBufferChar(checkoids, ',');
                               9301                 :            528 :             appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
                               9302                 :                :         }
                               9303                 :                :     }
                               9304                 :            189 :     appendPQExpBufferChar(tbloids, '}');
                               9305                 :            189 :     appendPQExpBufferChar(checkoids, '}');
                               9306                 :                : 
                               9307                 :                :     /*
                               9308                 :                :      * Find all the user attributes and their types.
                               9309                 :                :      *
                               9310                 :                :      * Since we only want to dump COLLATE clauses for attributes whose
                               9311                 :                :      * collation is different from their type's default, we use a CASE here to
                               9312                 :                :      * suppress uninteresting attcollations cheaply.
                               9313                 :                :      */
                               9314                 :            189 :     appendPQExpBufferStr(q,
                               9315                 :                :                          "SELECT\n"
                               9316                 :                :                          "a.attrelid,\n"
                               9317                 :                :                          "a.attnum,\n"
                               9318                 :                :                          "a.attname,\n"
                               9319                 :                :                          "a.attstattarget,\n"
                               9320                 :                :                          "a.attstorage,\n"
                               9321                 :                :                          "t.typstorage,\n"
                               9322                 :                :                          "a.atthasdef,\n"
                               9323                 :                :                          "a.attisdropped,\n"
                               9324                 :                :                          "a.attlen,\n"
                               9325                 :                :                          "a.attalign,\n"
                               9326                 :                :                          "a.attislocal,\n"
                               9327                 :                :                          "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
                               9328                 :                :                          "array_to_string(a.attoptions, ', ') AS attoptions,\n"
                               9329                 :                :                          "CASE WHEN a.attcollation <> t.typcollation "
                               9330                 :                :                          "THEN a.attcollation ELSE 0 END AS attcollation,\n"
                               9331                 :                :                          "pg_catalog.array_to_string(ARRAY("
                               9332                 :                :                          "SELECT pg_catalog.quote_ident(option_name) || "
                               9333                 :                :                          "' ' || pg_catalog.quote_literal(option_value) "
                               9334                 :                :                          "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
                               9335                 :                :                          "ORDER BY option_name"
                               9336                 :                :                          "), E',\n    ') AS attfdwoptions,\n");
                               9337                 :                : 
                               9338                 :                :     /*
                               9339                 :                :      * Find out any NOT NULL markings for each column.  In 18 and up we read
                               9340                 :                :      * pg_constraint to obtain the constraint name, and for valid constraints
                               9341                 :                :      * also pg_description to obtain its comment.  notnull_noinherit is set
                               9342                 :                :      * according to the NO INHERIT property.  For versions prior to 18, we
                               9343                 :                :      * store an empty string as the name when a constraint is marked as
                               9344                 :                :      * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
                               9345                 :                :      * without a name); also, such cases are never NO INHERIT.
                               9346                 :                :      *
                               9347                 :                :      * For invalid constraints, we need to store their OIDs for processing
                               9348                 :                :      * elsewhere, so we bring the pg_constraint.oid value when the constraint
                               9349                 :                :      * is invalid, and NULL otherwise.  Their comments are handled not here
                               9350                 :                :      * but by collectComments, because they're their own dumpable object.
                               9351                 :                :      *
                               9352                 :                :      * We track in notnull_islocal whether the constraint was defined directly
                               9353                 :                :      * in this table or via an ancestor, for binary upgrade.  flagInhAttrs
                               9354                 :                :      * might modify this later.
                               9355                 :                :      */
  353 alvherre@alvh.no-ip.     9356         [ +  - ]:            189 :     if (fout->remoteVersion >= 180000)
                               9357                 :            189 :         appendPQExpBufferStr(q,
                               9358                 :                :                              "co.conname AS notnull_name,\n"
                               9359                 :                :                              "CASE WHEN co.convalidated THEN pt.description"
                               9360                 :                :                              " ELSE NULL END AS notnull_comment,\n"
                               9361                 :                :                              "CASE WHEN NOT co.convalidated THEN co.oid "
                               9362                 :                :                              "ELSE NULL END AS notnull_invalidoid,\n"
                               9363                 :                :                              "co.connoinherit AS notnull_noinherit,\n"
                               9364                 :                :                              "co.conislocal AS notnull_islocal,\n");
                               9365                 :                :     else
  353 alvherre@alvh.no-ip.     9366                 :UBC           0 :         appendPQExpBufferStr(q,
                               9367                 :                :                              "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
                               9368                 :                :                              "NULL AS notnull_comment,\n"
                               9369                 :                :                              "NULL AS notnull_invalidoid,\n"
                               9370                 :                :                              "false AS notnull_noinherit,\n"
                               9371                 :                :                              "CASE WHEN a.attislocal THEN true\n"
                               9372                 :                :                              "     WHEN a.attnotnull AND NOT a.attislocal THEN true\n"
                               9373                 :                :                              "     ELSE false\n"
                               9374                 :                :                              "END AS notnull_islocal,\n");
                               9375                 :                : 
 1421 tgl@sss.pgh.pa.us        9376         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 140000)
                               9377                 :            189 :         appendPQExpBufferStr(q,
                               9378                 :                :                              "a.attcompression AS attcompression,\n");
                               9379                 :                :     else
 1421 tgl@sss.pgh.pa.us        9380                 :UBC           0 :         appendPQExpBufferStr(q,
                               9381                 :                :                              "'' AS attcompression,\n");
                               9382                 :                : 
 1421 tgl@sss.pgh.pa.us        9383         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 100000)
                               9384                 :            189 :         appendPQExpBufferStr(q,
                               9385                 :                :                              "a.attidentity,\n");
                               9386                 :                :     else
 1421 tgl@sss.pgh.pa.us        9387                 :UBC           0 :         appendPQExpBufferStr(q,
                               9388                 :                :                              "'' AS attidentity,\n");
                               9389                 :                : 
 1421 tgl@sss.pgh.pa.us        9390         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 110000)
                               9391                 :            189 :         appendPQExpBufferStr(q,
                               9392                 :                :                              "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
                               9393                 :                :                              "THEN a.attmissingval ELSE null END AS attmissingval,\n");
                               9394                 :                :     else
 1421 tgl@sss.pgh.pa.us        9395                 :UBC           0 :         appendPQExpBufferStr(q,
                               9396                 :                :                              "NULL AS attmissingval,\n");
                               9397                 :                : 
 1421 tgl@sss.pgh.pa.us        9398         [ +  - ]:CBC         189 :     if (fout->remoteVersion >= 120000)
                               9399                 :            189 :         appendPQExpBufferStr(q,
                               9400                 :                :                              "a.attgenerated\n");
                               9401                 :                :     else
 1421 tgl@sss.pgh.pa.us        9402                 :UBC           0 :         appendPQExpBufferStr(q,
                               9403                 :                :                              "'' AS attgenerated\n");
                               9404                 :                : 
                               9405                 :                :     /* need left join to pg_type to not fail on dropped columns ... */
 1421 tgl@sss.pgh.pa.us        9406                 :CBC         189 :     appendPQExpBuffer(q,
                               9407                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9408                 :                :                       "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
                               9409                 :                :                       "LEFT JOIN pg_catalog.pg_type t "
                               9410                 :                :                       "ON (a.atttypid = t.oid)\n",
                               9411                 :                :                       tbloids->data);
                               9412                 :                : 
                               9413                 :                :     /*
                               9414                 :                :      * In versions 18 and up, we need pg_constraint for explicit NOT NULL
                               9415                 :                :      * entries and pg_description to get their comments.
                               9416                 :                :      */
  353 alvherre@alvh.no-ip.     9417         [ +  - ]:            189 :     if (fout->remoteVersion >= 180000)
                               9418                 :            189 :         appendPQExpBufferStr(q,
                               9419                 :                :                              " LEFT JOIN pg_catalog.pg_constraint co ON "
                               9420                 :                :                              "(a.attrelid = co.conrelid\n"
                               9421                 :                :                              "   AND co.contype = 'n' AND "
                               9422                 :                :                              "co.conkey = array[a.attnum])\n"
                               9423                 :                :                              " LEFT JOIN pg_catalog.pg_description pt ON "
                               9424                 :                :                              "(pt.classoid = co.tableoid AND pt.objoid = co.oid)\n");
                               9425                 :                : 
                               9426                 :            189 :     appendPQExpBufferStr(q,
                               9427                 :                :                          "WHERE a.attnum > 0::pg_catalog.int2\n"
                               9428                 :                :                          "ORDER BY a.attrelid, a.attnum");
                               9429                 :                : 
 1421 tgl@sss.pgh.pa.us        9430                 :            189 :     res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9431                 :                : 
                               9432                 :            189 :     ntups = PQntuples(res);
                               9433                 :                : 
                               9434                 :            189 :     i_attrelid = PQfnumber(res, "attrelid");
                               9435                 :            189 :     i_attnum = PQfnumber(res, "attnum");
                               9436                 :            189 :     i_attname = PQfnumber(res, "attname");
                               9437                 :            189 :     i_atttypname = PQfnumber(res, "atttypname");
                               9438                 :            189 :     i_attstattarget = PQfnumber(res, "attstattarget");
                               9439                 :            189 :     i_attstorage = PQfnumber(res, "attstorage");
                               9440                 :            189 :     i_typstorage = PQfnumber(res, "typstorage");
                               9441                 :            189 :     i_attidentity = PQfnumber(res, "attidentity");
                               9442                 :            189 :     i_attgenerated = PQfnumber(res, "attgenerated");
                               9443                 :            189 :     i_attisdropped = PQfnumber(res, "attisdropped");
                               9444                 :            189 :     i_attlen = PQfnumber(res, "attlen");
                               9445                 :            189 :     i_attalign = PQfnumber(res, "attalign");
                               9446                 :            189 :     i_attislocal = PQfnumber(res, "attislocal");
  353 alvherre@alvh.no-ip.     9447                 :            189 :     i_notnull_name = PQfnumber(res, "notnull_name");
  123 alvherre@kurilemu.de     9448                 :            189 :     i_notnull_comment = PQfnumber(res, "notnull_comment");
  203 alvherre@alvh.no-ip.     9449                 :            189 :     i_notnull_invalidoid = PQfnumber(res, "notnull_invalidoid");
  353                          9450                 :            189 :     i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
                               9451                 :            189 :     i_notnull_islocal = PQfnumber(res, "notnull_islocal");
 1421 tgl@sss.pgh.pa.us        9452                 :            189 :     i_attoptions = PQfnumber(res, "attoptions");
                               9453                 :            189 :     i_attcollation = PQfnumber(res, "attcollation");
                               9454                 :            189 :     i_attcompression = PQfnumber(res, "attcompression");
                               9455                 :            189 :     i_attfdwoptions = PQfnumber(res, "attfdwoptions");
                               9456                 :            189 :     i_attmissingval = PQfnumber(res, "attmissingval");
                               9457                 :            189 :     i_atthasdef = PQfnumber(res, "atthasdef");
                               9458                 :                : 
                               9459                 :                :     /* Within the next loop, we'll accumulate OIDs of tables with defaults */
  929 alvherre@alvh.no-ip.     9460                 :            189 :     resetPQExpBuffer(tbloids);
                               9461                 :            189 :     appendPQExpBufferChar(tbloids, '{');
                               9462                 :                : 
                               9463                 :                :     /*
                               9464                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               9465                 :                :      * r is handled by the inner loop.
                               9466                 :                :      */
 1421 tgl@sss.pgh.pa.us        9467                 :            189 :     curtblindx = -1;
                               9468         [ +  + ]:           6690 :     for (int r = 0; r < ntups;)
                               9469                 :                :     {
                               9470                 :           6501 :         Oid         attrelid = atooid(PQgetvalue(res, r, i_attrelid));
                               9471                 :           6501 :         TableInfo  *tbinfo = NULL;
                               9472                 :                :         int         numatts;
                               9473                 :                :         bool        hasdefaults;
                               9474                 :                : 
                               9475                 :                :         /* Count rows for this table */
                               9476         [ +  + ]:          24625 :         for (numatts = 1; numatts < ntups - r; numatts++)
                               9477         [ +  + ]:          24483 :             if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
                               9478                 :           6359 :                 break;
                               9479                 :                : 
                               9480                 :                :         /*
                               9481                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               9482                 :                :          * order.
                               9483                 :                :          */
                               9484         [ +  - ]:          34508 :         while (++curtblindx < numTables)
                               9485                 :                :         {
                               9486                 :          34508 :             tbinfo = &tblinfo[curtblindx];
                               9487         [ +  + ]:          34508 :             if (tbinfo->dobj.catId.oid == attrelid)
                               9488                 :           6501 :                 break;
                               9489                 :                :         }
                               9490         [ -  + ]:           6501 :         if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        9491                 :UBC           0 :             pg_fatal("unrecognized table OID %u", attrelid);
                               9492                 :                :         /* cross-check that we only got requested tables */
 1421 tgl@sss.pgh.pa.us        9493         [ +  - ]:CBC        6501 :         if (tbinfo->relkind == RELKIND_SEQUENCE ||
  101 nathan@postgresql.or     9494         [ +  + ]:GNC        6501 :             (!tbinfo->interesting &&
                               9495   [ +  -  +  - ]:             72 :              !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
                               9496         [ +  + ]:             72 :                (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
                               9497         [ -  + ]:             36 :                 tbinfo->dobj.catId.oid == SharedDependRelationId))))
 1298 tgl@sss.pgh.pa.us        9498                 :UBC           0 :             pg_fatal("unexpected column data for table \"%s\"",
                               9499                 :                :                      tbinfo->dobj.name);
                               9500                 :                : 
                               9501                 :                :         /* Save data for this table */
 1421 tgl@sss.pgh.pa.us        9502                 :CBC        6501 :         tbinfo->numatts = numatts;
                               9503                 :           6501 :         tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
                               9504                 :           6501 :         tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
                               9505                 :           6501 :         tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
                               9506                 :           6501 :         tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
                               9507                 :           6501 :         tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
                               9508                 :           6501 :         tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
                               9509                 :           6501 :         tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
                               9510                 :           6501 :         tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
                               9511                 :           6501 :         tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
                               9512                 :           6501 :         tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
                               9513                 :           6501 :         tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
                               9514                 :           6501 :         tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               9515                 :           6501 :         tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
                               9516                 :           6501 :         tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
                               9517                 :           6501 :         tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               9518                 :           6501 :         tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
  353 alvherre@alvh.no-ip.     9519                 :           6501 :         tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
  123 alvherre@kurilemu.de     9520                 :           6501 :         tbinfo->notnull_comment = (char **) pg_malloc(numatts * sizeof(char *));
  182                          9521                 :           6501 :         tbinfo->notnull_invalid = (bool *) pg_malloc(numatts * sizeof(bool));
  353 alvherre@alvh.no-ip.     9522                 :           6501 :         tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
                               9523                 :           6501 :         tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
 1421 tgl@sss.pgh.pa.us        9524                 :           6501 :         tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
 8571                          9525                 :           6501 :         hasdefaults = false;
                               9526                 :                : 
 1421                          9527         [ +  + ]:          31126 :         for (int j = 0; j < numatts; j++, r++)
                               9528                 :                :         {
                               9529         [ -  + ]:          24625 :             if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
 1298 tgl@sss.pgh.pa.us        9530                 :UBC           0 :                 pg_fatal("invalid column numbering in table \"%s\"",
                               9531                 :                :                          tbinfo->dobj.name);
 1421 tgl@sss.pgh.pa.us        9532                 :CBC       24625 :             tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
                               9533                 :          24625 :             tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
  653 peter@eisentraut.org     9534         [ +  + ]:          24625 :             if (PQgetisnull(res, r, i_attstattarget))
                               9535                 :          24585 :                 tbinfo->attstattarget[j] = -1;
                               9536                 :                :             else
                               9537                 :             40 :                 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
 1421 tgl@sss.pgh.pa.us        9538                 :          24625 :             tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
                               9539                 :          24625 :             tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
                               9540                 :          24625 :             tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
                               9541                 :          24625 :             tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
 3126 peter_e@gmx.net          9542   [ +  +  +  + ]:          24625 :             tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
 1421 tgl@sss.pgh.pa.us        9543                 :          24625 :             tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
                               9544                 :          24625 :             tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
                               9545                 :          24625 :             tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
                               9546                 :          24625 :             tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
                               9547                 :                : 
                               9548                 :                :             /* Handle not-null constraint name and flags */
  353 alvherre@alvh.no-ip.     9549                 :          24625 :             determineNotNullFlags(fout, res, r,
                               9550                 :                :                                   tbinfo, j,
                               9551                 :                :                                   i_notnull_name,
                               9552                 :                :                                   i_notnull_comment,
                               9553                 :                :                                   i_notnull_invalidoid,
                               9554                 :                :                                   i_notnull_noinherit,
                               9555                 :                :                                   i_notnull_islocal,
                               9556                 :                :                                   &invalidnotnulloids);
                               9557                 :                : 
  123 alvherre@kurilemu.de     9558                 :          24625 :             tbinfo->notnull_comment[j] = PQgetisnull(res, r, i_notnull_comment) ?
                               9559         [ +  + ]:          24625 :                 NULL : pg_strdup(PQgetvalue(res, r, i_notnull_comment));
 1421 tgl@sss.pgh.pa.us        9560                 :          24625 :             tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
                               9561                 :          24625 :             tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
                               9562                 :          24625 :             tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
                               9563                 :          24625 :             tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
                               9564                 :          24625 :             tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
 7729 bruce@momjian.us         9565                 :          24625 :             tbinfo->attrdefs[j] = NULL; /* fix below */
 1421 tgl@sss.pgh.pa.us        9566         [ +  + ]:          24625 :             if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
 8571                          9567                 :           1268 :                 hasdefaults = true;
                               9568                 :                :         }
                               9569                 :                : 
 1421                          9570         [ +  + ]:           6501 :         if (hasdefaults)
                               9571                 :                :         {
                               9572                 :                :             /* Collect OIDs of interesting tables that have defaults */
  929 alvherre@alvh.no-ip.     9573         [ +  + ]:            952 :             if (tbloids->len > 1) /* do we have more than the '{'? */
                               9574                 :            884 :                 appendPQExpBufferChar(tbloids, ',');
                               9575                 :            952 :             appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               9576                 :                :         }
                               9577                 :                :     }
                               9578                 :                : 
                               9579                 :                :     /* If invalidnotnulloids has any data, finalize it */
  203                          9580         [ +  + ]:            189 :     if (invalidnotnulloids != NULL)
                               9581                 :             43 :         appendPQExpBufferChar(invalidnotnulloids, '}');
                               9582                 :                : 
 1421 tgl@sss.pgh.pa.us        9583                 :            189 :     PQclear(res);
                               9584                 :                : 
                               9585                 :                :     /*
                               9586                 :                :      * Now get info about column defaults.  This is skipped for a data-only
                               9587                 :                :      * dump, as it is only needed for table schemas.
                               9588                 :                :      */
  336 nathan@postgresql.or     9589   [ +  +  +  + ]:            189 :     if (dopt->dumpSchema && tbloids->len > 1)
                               9590                 :                :     {
                               9591                 :                :         AttrDefInfo *attrdefs;
                               9592                 :                :         int         numDefaults;
 1421 tgl@sss.pgh.pa.us        9593                 :             60 :         TableInfo  *tbinfo = NULL;
                               9594                 :                : 
                               9595                 :             60 :         pg_log_info("finding table default expressions");
                               9596                 :                : 
  929 alvherre@alvh.no-ip.     9597                 :             60 :         appendPQExpBufferChar(tbloids, '}');
                               9598                 :                : 
 1421 tgl@sss.pgh.pa.us        9599                 :             60 :         printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
                               9600                 :                :                           "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
                               9601                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9602                 :                :                           "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
                               9603                 :                :                           "ORDER BY a.adrelid, a.adnum",
                               9604                 :                :                           tbloids->data);
                               9605                 :                : 
                               9606                 :             60 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9607                 :                : 
                               9608                 :             60 :         numDefaults = PQntuples(res);
                               9609                 :             60 :         attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
                               9610                 :                : 
                               9611                 :             60 :         curtblindx = -1;
                               9612         [ +  + ]:           1230 :         for (int j = 0; j < numDefaults; j++)
                               9613                 :                :         {
                               9614                 :           1170 :             Oid         adtableoid = atooid(PQgetvalue(res, j, 0));
                               9615                 :           1170 :             Oid         adoid = atooid(PQgetvalue(res, j, 1));
                               9616                 :           1170 :             Oid         adrelid = atooid(PQgetvalue(res, j, 2));
                               9617                 :           1170 :             int         adnum = atoi(PQgetvalue(res, j, 3));
                               9618                 :           1170 :             char       *adsrc = PQgetvalue(res, j, 4);
                               9619                 :                : 
                               9620                 :                :             /*
                               9621                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9622                 :                :              * OID order.
                               9623                 :                :              */
                               9624   [ +  +  +  + ]:           1170 :             if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
                               9625                 :                :             {
                               9626         [ +  - ]:          18712 :                 while (++curtblindx < numTables)
                               9627                 :                :                 {
                               9628                 :          18712 :                     tbinfo = &tblinfo[curtblindx];
                               9629         [ +  + ]:          18712 :                     if (tbinfo->dobj.catId.oid == adrelid)
                               9630                 :            884 :                         break;
                               9631                 :                :                 }
                               9632         [ -  + ]:            884 :                 if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        9633                 :UBC           0 :                     pg_fatal("unrecognized table OID %u", adrelid);
                               9634                 :                :             }
                               9635                 :                : 
 1421 tgl@sss.pgh.pa.us        9636   [ +  -  -  + ]:CBC        1170 :             if (adnum <= 0 || adnum > tbinfo->numatts)
 1298 tgl@sss.pgh.pa.us        9637                 :UBC           0 :                 pg_fatal("invalid adnum value %d for table \"%s\"",
                               9638                 :                :                          adnum, tbinfo->dobj.name);
                               9639                 :                : 
                               9640                 :                :             /*
                               9641                 :                :              * dropped columns shouldn't have defaults, but just in case,
                               9642                 :                :              * ignore 'em
                               9643                 :                :              */
 1421 tgl@sss.pgh.pa.us        9644         [ -  + ]:CBC        1170 :             if (tbinfo->attisdropped[adnum - 1])
 1421 tgl@sss.pgh.pa.us        9645                 :UBC           0 :                 continue;
                               9646                 :                : 
 1421 tgl@sss.pgh.pa.us        9647                 :CBC        1170 :             attrdefs[j].dobj.objType = DO_ATTRDEF;
                               9648                 :           1170 :             attrdefs[j].dobj.catId.tableoid = adtableoid;
                               9649                 :           1170 :             attrdefs[j].dobj.catId.oid = adoid;
                               9650                 :           1170 :             AssignDumpId(&attrdefs[j].dobj);
                               9651                 :           1170 :             attrdefs[j].adtable = tbinfo;
                               9652                 :           1170 :             attrdefs[j].adnum = adnum;
                               9653                 :           1170 :             attrdefs[j].adef_expr = pg_strdup(adsrc);
                               9654                 :                : 
                               9655                 :           1170 :             attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
                               9656                 :           1170 :             attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
                               9657                 :                : 
                               9658                 :           1170 :             attrdefs[j].dobj.dump = tbinfo->dobj.dump;
                               9659                 :                : 
                               9660                 :                :             /*
                               9661                 :                :              * Figure out whether the default/generation expression should be
                               9662                 :                :              * dumped as part of the main CREATE TABLE (or similar) command or
                               9663                 :                :              * as a separate ALTER TABLE (or similar) command. The preference
                               9664                 :                :              * is to put it into the CREATE command, but in some cases that's
                               9665                 :                :              * not possible.
                               9666                 :                :              */
                               9667         [ +  + ]:           1170 :             if (tbinfo->attgenerated[adnum - 1])
                               9668                 :                :             {
                               9669                 :                :                 /*
                               9670                 :                :                  * Column generation expressions cannot be dumped separately,
                               9671                 :                :                  * because there is no syntax for it.  By setting separate to
                               9672                 :                :                  * false here we prevent the "default" from being processed as
                               9673                 :                :                  * its own dumpable object.  Later, flagInhAttrs() will mark
                               9674                 :                :                  * it as not to be dumped at all, if possible (that is, if it
                               9675                 :                :                  * can be inherited from a parent).
                               9676                 :                :                  */
                               9677                 :            656 :                 attrdefs[j].separate = false;
                               9678                 :                :             }
                               9679         [ +  + ]:            514 :             else if (tbinfo->relkind == RELKIND_VIEW)
                               9680                 :                :             {
                               9681                 :                :                 /*
                               9682                 :                :                  * Defaults on a VIEW must always be dumped as separate ALTER
                               9683                 :                :                  * TABLE commands.
                               9684                 :                :                  */
                               9685                 :             32 :                 attrdefs[j].separate = true;
                               9686                 :                :             }
                               9687         [ +  + ]:            482 :             else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
                               9688                 :                :             {
                               9689                 :                :                 /* column will be suppressed, print default separately */
                               9690                 :              4 :                 attrdefs[j].separate = true;
                               9691                 :                :             }
                               9692                 :                :             else
                               9693                 :                :             {
                               9694                 :            478 :                 attrdefs[j].separate = false;
                               9695                 :                :             }
                               9696                 :                : 
                               9697         [ +  + ]:           1170 :             if (!attrdefs[j].separate)
                               9698                 :                :             {
                               9699                 :                :                 /*
                               9700                 :                :                  * Mark the default as needing to appear before the table, so
                               9701                 :                :                  * that any dependencies it has must be emitted before the
                               9702                 :                :                  * CREATE TABLE.  If this is not possible, we'll change to
                               9703                 :                :                  * "separate" mode while sorting dependencies.
                               9704                 :                :                  */
                               9705                 :           1134 :                 addObjectDependency(&tbinfo->dobj,
                               9706                 :           1134 :                                     attrdefs[j].dobj.dumpId);
                               9707                 :                :             }
                               9708                 :                : 
                               9709                 :           1170 :             tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
                               9710                 :                :         }
                               9711                 :                : 
                               9712                 :             60 :         PQclear(res);
                               9713                 :                :     }
                               9714                 :                : 
                               9715                 :                :     /*
                               9716                 :                :      * Get info about NOT NULL NOT VALID constraints.  This is skipped for a
                               9717                 :                :      * data-only dump, as it is only needed for table schemas.
                               9718                 :                :      */
  203 alvherre@alvh.no-ip.     9719   [ +  +  +  + ]:            189 :     if (dopt->dumpSchema && invalidnotnulloids)
                               9720                 :                :     {
                               9721                 :                :         ConstraintInfo *constrs;
                               9722                 :                :         int         numConstrs;
                               9723                 :                :         int         i_tableoid;
                               9724                 :                :         int         i_oid;
                               9725                 :                :         int         i_conrelid;
                               9726                 :                :         int         i_conname;
                               9727                 :                :         int         i_consrc;
                               9728                 :                :         int         i_conislocal;
                               9729                 :                : 
  133 peter@eisentraut.org     9730                 :             37 :         pg_log_info("finding invalid not-null constraints");
                               9731                 :                : 
  203 alvherre@alvh.no-ip.     9732                 :             37 :         resetPQExpBuffer(q);
                               9733                 :             37 :         appendPQExpBuffer(q,
                               9734                 :                :                           "SELECT c.tableoid, c.oid, conrelid, conname, "
                               9735                 :                :                           "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
                               9736                 :                :                           "conislocal, convalidated "
                               9737                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(conoid)\n"
                               9738                 :                :                           "JOIN pg_catalog.pg_constraint c ON (src.conoid = c.oid)\n"
                               9739                 :                :                           "ORDER BY c.conrelid, c.conname",
                               9740                 :             37 :                           invalidnotnulloids->data);
                               9741                 :                : 
                               9742                 :             37 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9743                 :                : 
                               9744                 :             37 :         numConstrs = PQntuples(res);
                               9745                 :             37 :         constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
                               9746                 :                : 
                               9747                 :             37 :         i_tableoid = PQfnumber(res, "tableoid");
                               9748                 :             37 :         i_oid = PQfnumber(res, "oid");
                               9749                 :             37 :         i_conrelid = PQfnumber(res, "conrelid");
                               9750                 :             37 :         i_conname = PQfnumber(res, "conname");
                               9751                 :             37 :         i_consrc = PQfnumber(res, "consrc");
                               9752                 :             37 :         i_conislocal = PQfnumber(res, "conislocal");
                               9753                 :                : 
                               9754                 :                :         /* As above, this loop iterates once per table, not once per row */
                               9755                 :             37 :         curtblindx = -1;
                               9756         [ +  + ]:            104 :         for (int j = 0; j < numConstrs;)
                               9757                 :                :         {
                               9758                 :             67 :             Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               9759                 :             67 :             TableInfo  *tbinfo = NULL;
                               9760                 :                :             int         numcons;
                               9761                 :                : 
                               9762                 :                :             /* Count rows for this table */
                               9763         [ +  + ]:             67 :             for (numcons = 1; numcons < numConstrs - j; numcons++)
                               9764         [ +  - ]:             30 :                 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
                               9765                 :             30 :                     break;
                               9766                 :                : 
                               9767                 :                :             /*
                               9768                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9769                 :                :              * OID order.
                               9770                 :                :              */
                               9771         [ +  - ]:          12534 :             while (++curtblindx < numTables)
                               9772                 :                :             {
                               9773                 :          12534 :                 tbinfo = &tblinfo[curtblindx];
                               9774         [ +  + ]:          12534 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               9775                 :             67 :                     break;
                               9776                 :                :             }
                               9777         [ -  + ]:             67 :             if (curtblindx >= numTables)
  203 alvherre@alvh.no-ip.     9778                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               9779                 :                : 
  203 alvherre@alvh.no-ip.     9780         [ +  + ]:CBC         134 :             for (int c = 0; c < numcons; c++, j++)
                               9781                 :                :             {
                               9782                 :             67 :                 constrs[j].dobj.objType = DO_CONSTRAINT;
                               9783                 :             67 :                 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               9784                 :             67 :                 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               9785                 :             67 :                 AssignDumpId(&constrs[j].dobj);
                               9786                 :             67 :                 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               9787                 :             67 :                 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
                               9788                 :             67 :                 constrs[j].contable = tbinfo;
                               9789                 :             67 :                 constrs[j].condomain = NULL;
                               9790                 :             67 :                 constrs[j].contype = 'n';
                               9791                 :             67 :                 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
                               9792                 :             67 :                 constrs[j].confrelid = InvalidOid;
                               9793                 :             67 :                 constrs[j].conindex = 0;
                               9794                 :             67 :                 constrs[j].condeferrable = false;
                               9795                 :             67 :                 constrs[j].condeferred = false;
                               9796                 :             67 :                 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
                               9797                 :                : 
                               9798                 :                :                 /*
                               9799                 :                :                  * All invalid not-null constraints must be dumped separately,
                               9800                 :                :                  * because CREATE TABLE would not create them as invalid, and
                               9801                 :                :                  * also because they must be created after potentially
                               9802                 :                :                  * violating data has been loaded.
                               9803                 :                :                  */
                               9804                 :             67 :                 constrs[j].separate = true;
                               9805                 :                : 
                               9806                 :             67 :                 constrs[j].dobj.dump = tbinfo->dobj.dump;
                               9807                 :                :             }
                               9808                 :                :         }
                               9809                 :             37 :         PQclear(res);
                               9810                 :                :     }
                               9811                 :                : 
                               9812                 :                :     /*
                               9813                 :                :      * Get info about table CHECK constraints.  This is skipped for a
                               9814                 :                :      * data-only dump, as it is only needed for table schemas.
                               9815                 :                :      */
  336 nathan@postgresql.or     9816   [ +  +  +  + ]:            189 :     if (dopt->dumpSchema && checkoids->len > 2)
                               9817                 :                :     {
                               9818                 :                :         ConstraintInfo *constrs;
                               9819                 :                :         int         numConstrs;
                               9820                 :                :         int         i_tableoid;
                               9821                 :                :         int         i_oid;
                               9822                 :                :         int         i_conrelid;
                               9823                 :                :         int         i_conname;
                               9824                 :                :         int         i_consrc;
                               9825                 :                :         int         i_conislocal;
                               9826                 :                :         int         i_convalidated;
                               9827                 :                : 
 1421 tgl@sss.pgh.pa.us        9828                 :             61 :         pg_log_info("finding table check constraints");
                               9829                 :                : 
                               9830                 :             61 :         resetPQExpBuffer(q);
                               9831                 :             61 :         appendPQExpBuffer(q,
                               9832                 :                :                           "SELECT c.tableoid, c.oid, conrelid, conname, "
                               9833                 :                :                           "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
                               9834                 :                :                           "conislocal, convalidated "
                               9835                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9836                 :                :                           "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               9837                 :                :                           "WHERE contype = 'c' "
                               9838                 :                :                           "ORDER BY c.conrelid, c.conname",
                               9839                 :                :                           checkoids->data);
                               9840                 :                : 
                               9841                 :             61 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9842                 :                : 
                               9843                 :             61 :         numConstrs = PQntuples(res);
                               9844                 :             61 :         constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
                               9845                 :                : 
                               9846                 :             61 :         i_tableoid = PQfnumber(res, "tableoid");
                               9847                 :             61 :         i_oid = PQfnumber(res, "oid");
                               9848                 :             61 :         i_conrelid = PQfnumber(res, "conrelid");
                               9849                 :             61 :         i_conname = PQfnumber(res, "conname");
                               9850                 :             61 :         i_consrc = PQfnumber(res, "consrc");
                               9851                 :             61 :         i_conislocal = PQfnumber(res, "conislocal");
                               9852                 :             61 :         i_convalidated = PQfnumber(res, "convalidated");
                               9853                 :                : 
                               9854                 :                :         /* As above, this loop iterates once per table, not once per row */
                               9855                 :             61 :         curtblindx = -1;
                               9856         [ +  + ]:            538 :         for (int j = 0; j < numConstrs;)
                               9857                 :                :         {
                               9858                 :            477 :             Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               9859                 :            477 :             TableInfo  *tbinfo = NULL;
                               9860                 :                :             int         numcons;
                               9861                 :                : 
                               9862                 :                :             /* Count rows for this table */
                               9863         [ +  + ]:            612 :             for (numcons = 1; numcons < numConstrs - j; numcons++)
                               9864         [ +  + ]:            551 :                 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
                               9865                 :            416 :                     break;
                               9866                 :                : 
                               9867                 :                :             /*
                               9868                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9869                 :                :              * OID order.
                               9870                 :                :              */
                               9871         [ +  - ]:          18033 :             while (++curtblindx < numTables)
                               9872                 :                :             {
                               9873                 :          18033 :                 tbinfo = &tblinfo[curtblindx];
                               9874         [ +  + ]:          18033 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               9875                 :            477 :                     break;
                               9876                 :                :             }
                               9877         [ -  + ]:            477 :             if (curtblindx >= numTables)
 1298 tgl@sss.pgh.pa.us        9878                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               9879                 :                : 
 1421 tgl@sss.pgh.pa.us        9880         [ -  + ]:CBC         477 :             if (numcons != tbinfo->ncheck)
                               9881                 :                :             {
 2401 peter@eisentraut.org     9882                 :UBC           0 :                 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
                               9883                 :                :                                       "expected %d check constraints on table \"%s\" but found %d",
                               9884                 :                :                                       tbinfo->ncheck),
                               9885                 :                :                              tbinfo->ncheck, tbinfo->dobj.name, numcons);
 1298 tgl@sss.pgh.pa.us        9886                 :              0 :                 pg_log_error_hint("The system catalogs might be corrupted.");
 5002 rhaas@postgresql.org     9887                 :              0 :                 exit_nicely(1);
                               9888                 :                :             }
                               9889                 :                : 
 1421 tgl@sss.pgh.pa.us        9890                 :CBC         477 :             tbinfo->checkexprs = constrs + j;
                               9891                 :                : 
                               9892         [ +  + ]:           1089 :             for (int c = 0; c < numcons; c++, j++)
                               9893                 :                :             {
                               9894                 :            612 :                 bool        validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
                               9895                 :                : 
 7996                          9896                 :            612 :                 constrs[j].dobj.objType = DO_CONSTRAINT;
 1421                          9897                 :            612 :                 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               9898                 :            612 :                 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
 7996                          9899                 :            612 :                 AssignDumpId(&constrs[j].dobj);
 1421                          9900                 :            612 :                 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
 7908                          9901                 :            612 :                 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
 7996                          9902                 :            612 :                 constrs[j].contable = tbinfo;
                               9903                 :            612 :                 constrs[j].condomain = NULL;
                               9904                 :            612 :                 constrs[j].contype = 'c';
 1421                          9905                 :            612 :                 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
 6258                          9906                 :            612 :                 constrs[j].confrelid = InvalidOid;
 7996                          9907                 :            612 :                 constrs[j].conindex = 0;
 5934                          9908                 :            612 :                 constrs[j].condeferrable = false;
                               9909                 :            612 :                 constrs[j].condeferred = false;
 1421                          9910                 :            612 :                 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
                               9911                 :                : 
                               9912                 :                :                 /*
                               9913                 :                :                  * An unvalidated constraint needs to be dumped separately, so
                               9914                 :                :                  * that potentially-violating existing data is loaded before
                               9915                 :                :                  * the constraint.
                               9916                 :                :                  */
 4938 alvherre@alvh.no-ip.     9917                 :            612 :                 constrs[j].separate = !validated;
                               9918                 :                : 
 7179 tgl@sss.pgh.pa.us        9919                 :            612 :                 constrs[j].dobj.dump = tbinfo->dobj.dump;
                               9920                 :                : 
                               9921                 :                :                 /*
                               9922                 :                :                  * Mark the constraint as needing to appear before the table
                               9923                 :                :                  * --- this is so that any other dependencies of the
                               9924                 :                :                  * constraint will be emitted before we try to create the
                               9925                 :                :                  * table.  If the constraint is to be dumped separately, it
                               9926                 :                :                  * will be dumped after data is loaded anyway, so don't do it.
                               9927                 :                :                  * (There's an automatic dependency in the opposite direction
                               9928                 :                :                  * anyway, so don't need to add one manually here.)
                               9929                 :                :                  */
 5075 alvherre@alvh.no-ip.     9930         [ +  + ]:            612 :                 if (!constrs[j].separate)
 5086                          9931                 :            547 :                     addObjectDependency(&tbinfo->dobj,
                               9932                 :            547 :                                         constrs[j].dobj.dumpId);
                               9933                 :                : 
                               9934                 :                :                 /*
                               9935                 :                :                  * We will detect later whether the constraint must be split
                               9936                 :                :                  * out from the table definition.
                               9937                 :                :                  */
                               9938                 :                :             }
                               9939                 :                :         }
                               9940                 :                : 
 1421 tgl@sss.pgh.pa.us        9941                 :             61 :         PQclear(res);
                               9942                 :                :     }
                               9943                 :                : 
 8851                          9944                 :            189 :     destroyPQExpBuffer(q);
 1421                          9945                 :            189 :     destroyPQExpBuffer(tbloids);
                               9946                 :            189 :     destroyPQExpBuffer(checkoids);
10702 scrappy@hub.org          9947                 :            189 : }
                               9948                 :                : 
                               9949                 :                : /*
                               9950                 :                :  * Based on the getTableAttrs query's row corresponding to one column, set
                               9951                 :                :  * the name and flags to handle a not-null constraint for that column in
                               9952                 :                :  * the tbinfo struct.
                               9953                 :                :  *
                               9954                 :                :  * Result row 'r' is for tbinfo's attribute 'j'.
                               9955                 :                :  *
                               9956                 :                :  * There are four possibilities:
                               9957                 :                :  * 1) the column has no not-null constraints. In that case, ->notnull_constrs
                               9958                 :                :  *    (the constraint name) remains NULL.
                               9959                 :                :  * 2) The column has a constraint with no name (this is the case when
                               9960                 :                :  *    constraints come from pre-18 servers).  In this case, ->notnull_constrs
                               9961                 :                :  *    is set to the empty string; dumpTableSchema will print just "NOT NULL".
                               9962                 :                :  * 3) The column has an invalid not-null constraint.  This must be treated
                               9963                 :                :  *    as a separate object (because it must be created after the table data
                               9964                 :                :  *    is loaded).  So we add its OID to invalidnotnulloids for processing
                               9965                 :                :  *    elsewhere and do nothing further with it here.  We distinguish this
                               9966                 :                :  *    case because the "notnull_invalidoid" column has been set to a non-NULL
                               9967                 :                :  *    value, which is the constraint OID.  Valid constraints have a null OID.
                               9968                 :                :  * 4) The column has a constraint with a known name; in that case
                               9969                 :                :  *    notnull_constrs carries that name and dumpTableSchema will print
                               9970                 :                :  *    "CONSTRAINT the_name NOT NULL".  However, if the name is the default
                               9971                 :                :  *    (table_column_not_null) and there's no comment on the constraint,
                               9972                 :                :  *    there's no need to print that name in the dump, so notnull_constrs
                               9973                 :                :  *    is set to the empty string and it behaves as case 2.
                               9974                 :                :  *
                               9975                 :                :  * In a child table that inherits from a parent already containing NOT NULL
                               9976                 :                :  * constraints and the columns in the child don't have their own NOT NULL
                               9977                 :                :  * declarations, we suppress printing constraints in the child: the
                               9978                 :                :  * constraints are acquired at the point where the child is attached to the
                               9979                 :                :  * parent.  This is tracked in ->notnull_islocal; for servers pre-18 this is
                               9980                 :                :  * set not here but in flagInhAttrs.  That flag is also used when the
                               9981                 :                :  * constraint was validated in a child but all its parent have it as NOT
                               9982                 :                :  * VALID.
                               9983                 :                :  *
                               9984                 :                :  * Any of these constraints might have the NO INHERIT bit.  If so we set
                               9985                 :                :  * ->notnull_noinh and NO INHERIT will be printed by dumpTableSchema.
                               9986                 :                :  *
                               9987                 :                :  * In case 4 above, the name comparison is a bit of a hack; it actually fails
                               9988                 :                :  * to do the right thing in all but the trivial case.  However, the downside
                               9989                 :                :  * of getting it wrong is simply that the name is printed rather than
                               9990                 :                :  * suppressed, so it's not a big deal.
                               9991                 :                :  *
                               9992                 :                :  * invalidnotnulloids is expected to be given as NULL; if any invalid not-null
                               9993                 :                :  * constraints are found, it is initialized and filled with the array of
                               9994                 :                :  * OIDs of such constraints, for later processing.
                               9995                 :                :  */
                               9996                 :                : static void
  353 alvherre@alvh.no-ip.     9997                 :          24625 : determineNotNullFlags(Archive *fout, PGresult *res, int r,
                               9998                 :                :                       TableInfo *tbinfo, int j,
                               9999                 :                :                       int i_notnull_name,
                              10000                 :                :                       int i_notnull_comment,
                              10001                 :                :                       int i_notnull_invalidoid,
                              10002                 :                :                       int i_notnull_noinherit,
                              10003                 :                :                       int i_notnull_islocal,
                              10004                 :                :                       PQExpBuffer *invalidnotnulloids)
                              10005                 :                : {
                              10006                 :          24625 :     DumpOptions *dopt = fout->dopt;
                              10007                 :                : 
                              10008                 :                :     /*
                              10009                 :                :      * If this not-null constraint is not valid, list its OID in
                              10010                 :                :      * invalidnotnulloids and do nothing further.  It'll be processed
                              10011                 :                :      * elsewhere later.
                              10012                 :                :      *
                              10013                 :                :      * Because invalid not-null constraints are rare, we don't want to malloc
                              10014                 :                :      * invalidnotnulloids until we're sure we're going it need it, which
                              10015                 :                :      * happens here.
                              10016                 :                :      */
  203                         10017         [ +  + ]:          24625 :     if (!PQgetisnull(res, r, i_notnull_invalidoid))
                              10018                 :                :     {
                              10019                 :             73 :         char       *constroid = PQgetvalue(res, r, i_notnull_invalidoid);
                              10020                 :                : 
                              10021         [ +  + ]:             73 :         if (*invalidnotnulloids == NULL)
                              10022                 :                :         {
                              10023                 :             43 :             *invalidnotnulloids = createPQExpBuffer();
                              10024                 :             43 :             appendPQExpBufferChar(*invalidnotnulloids, '{');
  193 drowley@postgresql.o    10025                 :             43 :             appendPQExpBufferStr(*invalidnotnulloids, constroid);
                              10026                 :                :         }
                              10027                 :                :         else
  203 alvherre@alvh.no-ip.    10028                 :             30 :             appendPQExpBuffer(*invalidnotnulloids, ",%s", constroid);
                              10029                 :                : 
                              10030                 :                :         /*
                              10031                 :                :          * Track when a parent constraint is invalid for the cases where a
                              10032                 :                :          * child constraint has been validated independenly.
                              10033                 :                :          */
  182 alvherre@kurilemu.de    10034                 :             73 :         tbinfo->notnull_invalid[j] = true;
                              10035                 :                : 
                              10036                 :                :         /* nothing else to do */
  203 alvherre@alvh.no-ip.    10037                 :             73 :         tbinfo->notnull_constrs[j] = NULL;
                              10038                 :             73 :         return;
                              10039                 :                :     }
                              10040                 :                : 
                              10041                 :                :     /*
                              10042                 :                :      * notnull_noinh is straight from the query result. notnull_islocal also,
                              10043                 :                :      * though flagInhAttrs may change that one later.
                              10044                 :                :      */
  353                         10045                 :          24552 :     tbinfo->notnull_noinh[j] = PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
                              10046                 :          24552 :     tbinfo->notnull_islocal[j] = PQgetvalue(res, r, i_notnull_islocal)[0] == 't';
  182 alvherre@kurilemu.de    10047                 :          24552 :     tbinfo->notnull_invalid[j] = false;
                              10048                 :                : 
                              10049                 :                :     /*
                              10050                 :                :      * Determine a constraint name to use.  If the column is not marked not-
                              10051                 :                :      * null, we set NULL which cues ... to do nothing.  An empty string says
                              10052                 :                :      * to print an unnamed NOT NULL, and anything else is a constraint name to
                              10053                 :                :      * use.
                              10054                 :                :      */
  353 alvherre@alvh.no-ip.    10055         [ -  + ]:          24552 :     if (fout->remoteVersion < 180000)
                              10056                 :                :     {
                              10057                 :                :         /*
                              10058                 :                :          * < 18 doesn't have not-null names, so an unnamed constraint is
                              10059                 :                :          * sufficient.
                              10060                 :                :          */
  353 alvherre@alvh.no-ip.    10061         [ #  # ]:UBC           0 :         if (PQgetisnull(res, r, i_notnull_name))
                              10062                 :              0 :             tbinfo->notnull_constrs[j] = NULL;
                              10063                 :                :         else
                              10064                 :              0 :             tbinfo->notnull_constrs[j] = "";
                              10065                 :                :     }
                              10066                 :                :     else
                              10067                 :                :     {
  353 alvherre@alvh.no-ip.    10068         [ +  + ]:CBC       24552 :         if (PQgetisnull(res, r, i_notnull_name))
                              10069                 :          21945 :             tbinfo->notnull_constrs[j] = NULL;
                              10070                 :                :         else
                              10071                 :                :         {
                              10072                 :                :             /*
                              10073                 :                :              * In binary upgrade of inheritance child tables, must have a
                              10074                 :                :              * constraint name that we can UPDATE later; same if there's a
                              10075                 :                :              * comment on the constraint.
                              10076                 :                :              */
  123 alvherre@kurilemu.de    10077         [ +  + ]:           2607 :             if ((dopt->binary_upgrade &&
                              10078         [ +  + ]:            327 :                  !tbinfo->ispartition &&
                              10079   [ +  -  +  + ]:           2856 :                  !tbinfo->notnull_islocal) ||
                              10080                 :           2607 :                 !PQgetisnull(res, r, i_notnull_comment))
                              10081                 :                :             {
  353 alvherre@alvh.no-ip.    10082                 :             48 :                 tbinfo->notnull_constrs[j] =
                              10083                 :             48 :                     pstrdup(PQgetvalue(res, r, i_notnull_name));
                              10084                 :                :             }
                              10085                 :                :             else
                              10086                 :                :             {
                              10087                 :                :                 char       *default_name;
                              10088                 :                : 
                              10089                 :                :                 /* XXX should match ChooseConstraintName better */
                              10090                 :           2559 :                 default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
                              10091                 :           2559 :                                         tbinfo->attnames[j]);
                              10092         [ +  + ]:           2559 :                 if (strcmp(default_name,
                              10093                 :           2559 :                            PQgetvalue(res, r, i_notnull_name)) == 0)
                              10094                 :           1695 :                     tbinfo->notnull_constrs[j] = "";
                              10095                 :                :                 else
                              10096                 :                :                 {
                              10097                 :            864 :                     tbinfo->notnull_constrs[j] =
                              10098                 :            864 :                         pstrdup(PQgetvalue(res, r, i_notnull_name));
                              10099                 :                :                 }
  257 tgl@sss.pgh.pa.us       10100                 :           2559 :                 free(default_name);
                              10101                 :                :             }
                              10102                 :                :         }
                              10103                 :                :     }
                              10104                 :                : }
                              10105                 :                : 
                              10106                 :                : /*
                              10107                 :                :  * Test whether a column should be printed as part of table's CREATE TABLE.
                              10108                 :                :  * Column number is zero-based.
                              10109                 :                :  *
                              10110                 :                :  * Normally this is always true, but it's false for dropped columns, as well
                              10111                 :                :  * as those that were inherited without any local definition.  (If we print
                              10112                 :                :  * such a column it will mistakenly get pg_attribute.attislocal set to true.)
                              10113                 :                :  * For partitions, it's always true, because we want the partitions to be
                              10114                 :                :  * created independently and ATTACH PARTITION used afterwards.
                              10115                 :                :  *
                              10116                 :                :  * In binary_upgrade mode, we must print all columns and fix the attislocal/
                              10117                 :                :  * attisdropped state later, so as to keep control of the physical column
                              10118                 :                :  * order.
                              10119                 :                :  *
                              10120                 :                :  * This function exists because there are scattered nonobvious places that
                              10121                 :                :  * must be kept in sync with this decision.
                              10122                 :                :  */
                              10123                 :                : bool
 1720 peter@eisentraut.org    10124                 :          40004 : shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
                              10125                 :                : {
 4031 alvherre@alvh.no-ip.    10126         [ +  + ]:          40004 :     if (dopt->binary_upgrade)
 5008 tgl@sss.pgh.pa.us       10127                 :           6214 :         return true;
 2331 alvherre@alvh.no-ip.    10128         [ +  + ]:          33790 :     if (tbinfo->attisdropped[colno])
                              10129                 :            726 :         return false;
                              10130   [ +  +  +  + ]:          33064 :     return (tbinfo->attislocal[colno] || tbinfo->ispartition);
                              10131                 :                : }
                              10132                 :                : 
                              10133                 :                : 
                              10134                 :                : /*
                              10135                 :                :  * getTSParsers:
                              10136                 :                :  *    get information about all text search parsers in the system catalogs
                              10137                 :                :  */
                              10138                 :                : void
  482 nathan@postgresql.or    10139                 :            189 : getTSParsers(Archive *fout)
                              10140                 :                : {
                              10141                 :                :     PGresult   *res;
                              10142                 :                :     int         ntups;
                              10143                 :                :     int         i;
                              10144                 :                :     PQExpBuffer query;
                              10145                 :                :     TSParserInfo *prsinfo;
                              10146                 :                :     int         i_tableoid;
                              10147                 :                :     int         i_oid;
                              10148                 :                :     int         i_prsname;
                              10149                 :                :     int         i_prsnamespace;
                              10150                 :                :     int         i_prsstart;
                              10151                 :                :     int         i_prstoken;
                              10152                 :                :     int         i_prsend;
                              10153                 :                :     int         i_prsheadline;
                              10154                 :                :     int         i_prslextype;
                              10155                 :                : 
 4976 peter_e@gmx.net         10156                 :            189 :     query = createPQExpBuffer();
                              10157                 :                : 
                              10158                 :                :     /*
                              10159                 :                :      * find all text search objects, including builtin ones; we filter out
                              10160                 :                :      * system-defined objects at dump-out time.
                              10161                 :                :      */
                              10162                 :                : 
 4361 heikki.linnakangas@i    10163                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
                              10164                 :                :                          "prsstart::oid, prstoken::oid, "
                              10165                 :                :                          "prsend::oid, prsheadline::oid, prslextype::oid "
                              10166                 :                :                          "FROM pg_ts_parser");
                              10167                 :                : 
 5011 rhaas@postgresql.org    10168                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10169                 :                : 
 6642 tgl@sss.pgh.pa.us       10170                 :            189 :     ntups = PQntuples(res);
                              10171                 :                : 
 5085 bruce@momjian.us        10172                 :            189 :     prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
                              10173                 :                : 
 6642 tgl@sss.pgh.pa.us       10174                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                              10175                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10176                 :            189 :     i_prsname = PQfnumber(res, "prsname");
                              10177                 :            189 :     i_prsnamespace = PQfnumber(res, "prsnamespace");
                              10178                 :            189 :     i_prsstart = PQfnumber(res, "prsstart");
                              10179                 :            189 :     i_prstoken = PQfnumber(res, "prstoken");
                              10180                 :            189 :     i_prsend = PQfnumber(res, "prsend");
                              10181                 :            189 :     i_prsheadline = PQfnumber(res, "prsheadline");
                              10182                 :            189 :     i_prslextype = PQfnumber(res, "prslextype");
                              10183                 :                : 
                              10184         [ +  + ]:            423 :     for (i = 0; i < ntups; i++)
                              10185                 :                :     {
                              10186                 :            234 :         prsinfo[i].dobj.objType = DO_TSPARSER;
                              10187                 :            234 :         prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10188                 :            234 :         prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10189                 :            234 :         AssignDumpId(&prsinfo[i].dobj);
 5085 bruce@momjian.us        10190                 :            234 :         prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
 5012 rhaas@postgresql.org    10191                 :            468 :         prsinfo[i].dobj.namespace =
 1889 peter@eisentraut.org    10192                 :            234 :             findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
 6642 tgl@sss.pgh.pa.us       10193                 :            234 :         prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
                              10194                 :            234 :         prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
                              10195                 :            234 :         prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
                              10196                 :            234 :         prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
                              10197                 :            234 :         prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
                              10198                 :                : 
                              10199                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10200                 :            234 :         selectDumpableObject(&(prsinfo[i].dobj), fout);
                              10201                 :                :     }
                              10202                 :                : 
 6642 tgl@sss.pgh.pa.us       10203                 :            189 :     PQclear(res);
                              10204                 :                : 
                              10205                 :            189 :     destroyPQExpBuffer(query);
                              10206                 :            189 : }
                              10207                 :                : 
                              10208                 :                : /*
                              10209                 :                :  * getTSDictionaries:
                              10210                 :                :  *    get information about all text search dictionaries in the system catalogs
                              10211                 :                :  */
                              10212                 :                : void
  482 nathan@postgresql.or    10213                 :            189 : getTSDictionaries(Archive *fout)
                              10214                 :                : {
                              10215                 :                :     PGresult   *res;
                              10216                 :                :     int         ntups;
                              10217                 :                :     int         i;
                              10218                 :                :     PQExpBuffer query;
                              10219                 :                :     TSDictInfo *dictinfo;
                              10220                 :                :     int         i_tableoid;
                              10221                 :                :     int         i_oid;
                              10222                 :                :     int         i_dictname;
                              10223                 :                :     int         i_dictnamespace;
                              10224                 :                :     int         i_dictowner;
                              10225                 :                :     int         i_dicttemplate;
                              10226                 :                :     int         i_dictinitoption;
                              10227                 :                : 
 4976 peter_e@gmx.net         10228                 :            189 :     query = createPQExpBuffer();
                              10229                 :                : 
 1147 drowley@postgresql.o    10230                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
                              10231                 :                :                          "dictnamespace, dictowner, "
                              10232                 :                :                          "dicttemplate, dictinitoption "
                              10233                 :                :                          "FROM pg_ts_dict");
                              10234                 :                : 
 5011 rhaas@postgresql.org    10235                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10236                 :                : 
 6642 tgl@sss.pgh.pa.us       10237                 :            189 :     ntups = PQntuples(res);
                              10238                 :                : 
 5085 bruce@momjian.us        10239                 :            189 :     dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
                              10240                 :                : 
 6642 tgl@sss.pgh.pa.us       10241                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                              10242                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10243                 :            189 :     i_dictname = PQfnumber(res, "dictname");
                              10244                 :            189 :     i_dictnamespace = PQfnumber(res, "dictnamespace");
 1396                         10245                 :            189 :     i_dictowner = PQfnumber(res, "dictowner");
 6642                         10246                 :            189 :     i_dictinitoption = PQfnumber(res, "dictinitoption");
                              10247                 :            189 :     i_dicttemplate = PQfnumber(res, "dicttemplate");
                              10248                 :                : 
                              10249         [ +  + ]:           5967 :     for (i = 0; i < ntups; i++)
                              10250                 :                :     {
                              10251                 :           5778 :         dictinfo[i].dobj.objType = DO_TSDICT;
                              10252                 :           5778 :         dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10253                 :           5778 :         dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10254                 :           5778 :         AssignDumpId(&dictinfo[i].dobj);
 5085 bruce@momjian.us        10255                 :           5778 :         dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
 5012 rhaas@postgresql.org    10256                 :          11556 :         dictinfo[i].dobj.namespace =
 1889 peter@eisentraut.org    10257                 :           5778 :             findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
 1396 tgl@sss.pgh.pa.us       10258                 :           5778 :         dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
 6642                         10259                 :           5778 :         dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
                              10260         [ +  + ]:           5778 :         if (PQgetisnull(res, i, i_dictinitoption))
                              10261                 :            234 :             dictinfo[i].dictinitoption = NULL;
                              10262                 :                :         else
 5085 bruce@momjian.us        10263                 :           5544 :             dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
                              10264                 :                : 
                              10265                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10266                 :           5778 :         selectDumpableObject(&(dictinfo[i].dobj), fout);
                              10267                 :                :     }
                              10268                 :                : 
 6642 tgl@sss.pgh.pa.us       10269                 :            189 :     PQclear(res);
                              10270                 :                : 
                              10271                 :            189 :     destroyPQExpBuffer(query);
                              10272                 :            189 : }
                              10273                 :                : 
                              10274                 :                : /*
                              10275                 :                :  * getTSTemplates:
                              10276                 :                :  *    get information about all text search templates in the system catalogs
                              10277                 :                :  */
                              10278                 :                : void
  482 nathan@postgresql.or    10279                 :            189 : getTSTemplates(Archive *fout)
                              10280                 :                : {
                              10281                 :                :     PGresult   *res;
                              10282                 :                :     int         ntups;
                              10283                 :                :     int         i;
                              10284                 :                :     PQExpBuffer query;
                              10285                 :                :     TSTemplateInfo *tmplinfo;
                              10286                 :                :     int         i_tableoid;
                              10287                 :                :     int         i_oid;
                              10288                 :                :     int         i_tmplname;
                              10289                 :                :     int         i_tmplnamespace;
                              10290                 :                :     int         i_tmplinit;
                              10291                 :                :     int         i_tmpllexize;
                              10292                 :                : 
 4976 peter_e@gmx.net         10293                 :            189 :     query = createPQExpBuffer();
                              10294                 :                : 
 4361 heikki.linnakangas@i    10295                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
                              10296                 :                :                          "tmplnamespace, tmplinit::oid, tmpllexize::oid "
                              10297                 :                :                          "FROM pg_ts_template");
                              10298                 :                : 
 5011 rhaas@postgresql.org    10299                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10300                 :                : 
 6642 tgl@sss.pgh.pa.us       10301                 :            189 :     ntups = PQntuples(res);
                              10302                 :                : 
 5085 bruce@momjian.us        10303                 :            189 :     tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
                              10304                 :                : 
 6642 tgl@sss.pgh.pa.us       10305                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                              10306                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10307                 :            189 :     i_tmplname = PQfnumber(res, "tmplname");
                              10308                 :            189 :     i_tmplnamespace = PQfnumber(res, "tmplnamespace");
                              10309                 :            189 :     i_tmplinit = PQfnumber(res, "tmplinit");
                              10310                 :            189 :     i_tmpllexize = PQfnumber(res, "tmpllexize");
                              10311                 :                : 
                              10312         [ +  + ]:           1179 :     for (i = 0; i < ntups; i++)
                              10313                 :                :     {
                              10314                 :            990 :         tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
                              10315                 :            990 :         tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10316                 :            990 :         tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10317                 :            990 :         AssignDumpId(&tmplinfo[i].dobj);
 5085 bruce@momjian.us        10318                 :            990 :         tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
 5012 rhaas@postgresql.org    10319                 :           1980 :         tmplinfo[i].dobj.namespace =
 1889 peter@eisentraut.org    10320                 :            990 :             findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
 6642 tgl@sss.pgh.pa.us       10321                 :            990 :         tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
                              10322                 :            990 :         tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
                              10323                 :                : 
                              10324                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10325                 :            990 :         selectDumpableObject(&(tmplinfo[i].dobj), fout);
                              10326                 :                :     }
                              10327                 :                : 
 6642 tgl@sss.pgh.pa.us       10328                 :            189 :     PQclear(res);
                              10329                 :                : 
                              10330                 :            189 :     destroyPQExpBuffer(query);
                              10331                 :            189 : }
                              10332                 :                : 
                              10333                 :                : /*
                              10334                 :                :  * getTSConfigurations:
                              10335                 :                :  *    get information about all text search configurations
                              10336                 :                :  */
                              10337                 :                : void
  482 nathan@postgresql.or    10338                 :            189 : getTSConfigurations(Archive *fout)
                              10339                 :                : {
                              10340                 :                :     PGresult   *res;
                              10341                 :                :     int         ntups;
                              10342                 :                :     int         i;
                              10343                 :                :     PQExpBuffer query;
                              10344                 :                :     TSConfigInfo *cfginfo;
                              10345                 :                :     int         i_tableoid;
                              10346                 :                :     int         i_oid;
                              10347                 :                :     int         i_cfgname;
                              10348                 :                :     int         i_cfgnamespace;
                              10349                 :                :     int         i_cfgowner;
                              10350                 :                :     int         i_cfgparser;
                              10351                 :                : 
 4976 peter_e@gmx.net         10352                 :            189 :     query = createPQExpBuffer();
                              10353                 :                : 
 1147 drowley@postgresql.o    10354                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
                              10355                 :                :                          "cfgnamespace, cfgowner, cfgparser "
                              10356                 :                :                          "FROM pg_ts_config");
                              10357                 :                : 
 5011 rhaas@postgresql.org    10358                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10359                 :                : 
 6642 tgl@sss.pgh.pa.us       10360                 :            189 :     ntups = PQntuples(res);
                              10361                 :                : 
 5085 bruce@momjian.us        10362                 :            189 :     cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
                              10363                 :                : 
 6642 tgl@sss.pgh.pa.us       10364                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                              10365                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10366                 :            189 :     i_cfgname = PQfnumber(res, "cfgname");
                              10367                 :            189 :     i_cfgnamespace = PQfnumber(res, "cfgnamespace");
 1396                         10368                 :            189 :     i_cfgowner = PQfnumber(res, "cfgowner");
 6642                         10369                 :            189 :     i_cfgparser = PQfnumber(res, "cfgparser");
                              10370                 :                : 
                              10371         [ +  + ]:           5932 :     for (i = 0; i < ntups; i++)
                              10372                 :                :     {
                              10373                 :           5743 :         cfginfo[i].dobj.objType = DO_TSCONFIG;
                              10374                 :           5743 :         cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10375                 :           5743 :         cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10376                 :           5743 :         AssignDumpId(&cfginfo[i].dobj);
 5085 bruce@momjian.us        10377                 :           5743 :         cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
 5012 rhaas@postgresql.org    10378                 :          11486 :         cfginfo[i].dobj.namespace =
 1889 peter@eisentraut.org    10379                 :           5743 :             findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
 1396 tgl@sss.pgh.pa.us       10380                 :           5743 :         cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
 6642                         10381                 :           5743 :         cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
                              10382                 :                : 
                              10383                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10384                 :           5743 :         selectDumpableObject(&(cfginfo[i].dobj), fout);
                              10385                 :                :     }
                              10386                 :                : 
 6642 tgl@sss.pgh.pa.us       10387                 :            189 :     PQclear(res);
                              10388                 :                : 
                              10389                 :            189 :     destroyPQExpBuffer(query);
                              10390                 :            189 : }
                              10391                 :                : 
                              10392                 :                : /*
                              10393                 :                :  * getForeignDataWrappers:
                              10394                 :                :  *    get information about all foreign-data wrappers in the system catalogs
                              10395                 :                :  */
                              10396                 :                : void
  482 nathan@postgresql.or    10397                 :            189 : getForeignDataWrappers(Archive *fout)
                              10398                 :                : {
                              10399                 :                :     PGresult   *res;
                              10400                 :                :     int         ntups;
                              10401                 :                :     int         i;
                              10402                 :                :     PQExpBuffer query;
                              10403                 :                :     FdwInfo    *fdwinfo;
                              10404                 :                :     int         i_tableoid;
                              10405                 :                :     int         i_oid;
                              10406                 :                :     int         i_fdwname;
                              10407                 :                :     int         i_fdwowner;
                              10408                 :                :     int         i_fdwhandler;
                              10409                 :                :     int         i_fdwvalidator;
                              10410                 :                :     int         i_fdwacl;
                              10411                 :                :     int         i_acldefault;
                              10412                 :                :     int         i_fdwoptions;
                              10413                 :                : 
 4279 sfrost@snowman.net      10414                 :            189 :     query = createPQExpBuffer();
                              10415                 :                : 
 1147 drowley@postgresql.o    10416                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
                              10417                 :                :                          "fdwowner, "
                              10418                 :                :                          "fdwhandler::pg_catalog.regproc, "
                              10419                 :                :                          "fdwvalidator::pg_catalog.regproc, "
                              10420                 :                :                          "fdwacl, "
                              10421                 :                :                          "acldefault('F', fdwowner) AS acldefault, "
                              10422                 :                :                          "array_to_string(ARRAY("
                              10423                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                              10424                 :                :                          "quote_literal(option_value) "
                              10425                 :                :                          "FROM pg_options_to_table(fdwoptions) "
                              10426                 :                :                          "ORDER BY option_name"
                              10427                 :                :                          "), E',\n    ') AS fdwoptions "
                              10428                 :                :                          "FROM pg_foreign_data_wrapper");
                              10429                 :                : 
 5011 rhaas@postgresql.org    10430                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10431                 :                : 
 6156 peter_e@gmx.net         10432                 :            189 :     ntups = PQntuples(res);
                              10433                 :                : 
 5085 bruce@momjian.us        10434                 :            189 :     fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
                              10435                 :                : 
 5513 heikki.linnakangas@i    10436                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 6156 peter_e@gmx.net         10437                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10438                 :            189 :     i_fdwname = PQfnumber(res, "fdwname");
 1396 tgl@sss.pgh.pa.us       10439                 :            189 :     i_fdwowner = PQfnumber(res, "fdwowner");
 5364                         10440                 :            189 :     i_fdwhandler = PQfnumber(res, "fdwhandler");
 6089 peter_e@gmx.net         10441                 :            189 :     i_fdwvalidator = PQfnumber(res, "fdwvalidator");
 6156                         10442                 :            189 :     i_fdwacl = PQfnumber(res, "fdwacl");
 1421 tgl@sss.pgh.pa.us       10443                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
 6156 peter_e@gmx.net         10444                 :            189 :     i_fdwoptions = PQfnumber(res, "fdwoptions");
                              10445                 :                : 
                              10446         [ +  + ]:            260 :     for (i = 0; i < ntups; i++)
                              10447                 :                :     {
                              10448                 :             71 :         fdwinfo[i].dobj.objType = DO_FDW;
 5513 heikki.linnakangas@i    10449                 :             71 :         fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 6156 peter_e@gmx.net         10450                 :             71 :         fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10451                 :             71 :         AssignDumpId(&fdwinfo[i].dobj);
 5085 bruce@momjian.us        10452                 :             71 :         fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
 6156 peter_e@gmx.net         10453                 :             71 :         fdwinfo[i].dobj.namespace = NULL;
 1421 tgl@sss.pgh.pa.us       10454                 :             71 :         fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
                              10455                 :             71 :         fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10456                 :             71 :         fdwinfo[i].dacl.privtype = 0;
                              10457                 :             71 :         fdwinfo[i].dacl.initprivs = NULL;
 1396                         10458                 :             71 :         fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
 5085 bruce@momjian.us        10459                 :             71 :         fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
                              10460                 :             71 :         fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
                              10461                 :             71 :         fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
                              10462                 :                : 
                              10463                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10464                 :             71 :         selectDumpableObject(&(fdwinfo[i].dobj), fout);
                              10465                 :                : 
                              10466                 :                :         /* Mark whether FDW has an ACL */
 1421 tgl@sss.pgh.pa.us       10467         [ +  + ]:             71 :         if (!PQgetisnull(res, i, i_fdwacl))
                              10468                 :             45 :             fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10469                 :                :     }
                              10470                 :                : 
 6156 peter_e@gmx.net         10471                 :            189 :     PQclear(res);
                              10472                 :                : 
                              10473                 :            189 :     destroyPQExpBuffer(query);
                              10474                 :            189 : }
                              10475                 :                : 
                              10476                 :                : /*
                              10477                 :                :  * getForeignServers:
                              10478                 :                :  *    get information about all foreign servers in the system catalogs
                              10479                 :                :  */
                              10480                 :                : void
  482 nathan@postgresql.or    10481                 :            189 : getForeignServers(Archive *fout)
                              10482                 :                : {
                              10483                 :                :     PGresult   *res;
                              10484                 :                :     int         ntups;
                              10485                 :                :     int         i;
                              10486                 :                :     PQExpBuffer query;
                              10487                 :                :     ForeignServerInfo *srvinfo;
                              10488                 :                :     int         i_tableoid;
                              10489                 :                :     int         i_oid;
                              10490                 :                :     int         i_srvname;
                              10491                 :                :     int         i_srvowner;
                              10492                 :                :     int         i_srvfdw;
                              10493                 :                :     int         i_srvtype;
                              10494                 :                :     int         i_srvversion;
                              10495                 :                :     int         i_srvacl;
                              10496                 :                :     int         i_acldefault;
                              10497                 :                :     int         i_srvoptions;
                              10498                 :                : 
 4279 sfrost@snowman.net      10499                 :            189 :     query = createPQExpBuffer();
                              10500                 :                : 
 1147 drowley@postgresql.o    10501                 :            189 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
                              10502                 :                :                          "srvowner, "
                              10503                 :                :                          "srvfdw, srvtype, srvversion, srvacl, "
                              10504                 :                :                          "acldefault('S', srvowner) AS acldefault, "
                              10505                 :                :                          "array_to_string(ARRAY("
                              10506                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                              10507                 :                :                          "quote_literal(option_value) "
                              10508                 :                :                          "FROM pg_options_to_table(srvoptions) "
                              10509                 :                :                          "ORDER BY option_name"
                              10510                 :                :                          "), E',\n    ') AS srvoptions "
                              10511                 :                :                          "FROM pg_foreign_server");
                              10512                 :                : 
 5011 rhaas@postgresql.org    10513                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10514                 :                : 
 6156 peter_e@gmx.net         10515                 :            189 :     ntups = PQntuples(res);
                              10516                 :                : 
 5085 bruce@momjian.us        10517                 :            189 :     srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
                              10518                 :                : 
 5513 heikki.linnakangas@i    10519                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
 6156 peter_e@gmx.net         10520                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10521                 :            189 :     i_srvname = PQfnumber(res, "srvname");
 1396 tgl@sss.pgh.pa.us       10522                 :            189 :     i_srvowner = PQfnumber(res, "srvowner");
 6156 peter_e@gmx.net         10523                 :            189 :     i_srvfdw = PQfnumber(res, "srvfdw");
                              10524                 :            189 :     i_srvtype = PQfnumber(res, "srvtype");
                              10525                 :            189 :     i_srvversion = PQfnumber(res, "srvversion");
                              10526                 :            189 :     i_srvacl = PQfnumber(res, "srvacl");
 1421 tgl@sss.pgh.pa.us       10527                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
 6156 peter_e@gmx.net         10528                 :            189 :     i_srvoptions = PQfnumber(res, "srvoptions");
                              10529                 :                : 
                              10530         [ +  + ]:            264 :     for (i = 0; i < ntups; i++)
                              10531                 :                :     {
                              10532                 :             75 :         srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
 5513 heikki.linnakangas@i    10533                 :             75 :         srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 6156 peter_e@gmx.net         10534                 :             75 :         srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10535                 :             75 :         AssignDumpId(&srvinfo[i].dobj);
 5085 bruce@momjian.us        10536                 :             75 :         srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
 6156 peter_e@gmx.net         10537                 :             75 :         srvinfo[i].dobj.namespace = NULL;
 1421 tgl@sss.pgh.pa.us       10538                 :             75 :         srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
                              10539                 :             75 :         srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10540                 :             75 :         srvinfo[i].dacl.privtype = 0;
                              10541                 :             75 :         srvinfo[i].dacl.initprivs = NULL;
 1396                         10542                 :             75 :         srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
 6156 peter_e@gmx.net         10543                 :             75 :         srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
 5085 bruce@momjian.us        10544                 :             75 :         srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
                              10545                 :             75 :         srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
                              10546                 :             75 :         srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
                              10547                 :                : 
                              10548                 :                :         /* Decide whether we want to dump it */
 3491 sfrost@snowman.net      10549                 :             75 :         selectDumpableObject(&(srvinfo[i].dobj), fout);
                              10550                 :                : 
                              10551                 :                :         /* Servers have user mappings */
 1421 tgl@sss.pgh.pa.us       10552                 :             75 :         srvinfo[i].dobj.components |= DUMP_COMPONENT_USERMAP;
                              10553                 :                : 
                              10554                 :                :         /* Mark whether server has an ACL */
                              10555         [ +  + ]:             75 :         if (!PQgetisnull(res, i, i_srvacl))
                              10556                 :             45 :             srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10557                 :                :     }
                              10558                 :                : 
 6156 peter_e@gmx.net         10559                 :            189 :     PQclear(res);
                              10560                 :                : 
                              10561                 :            189 :     destroyPQExpBuffer(query);
                              10562                 :            189 : }
                              10563                 :                : 
                              10564                 :                : /*
                              10565                 :                :  * getDefaultACLs:
                              10566                 :                :  *    get information about all default ACL information in the system catalogs
                              10567                 :                :  */
                              10568                 :                : void
  482 nathan@postgresql.or    10569                 :            189 : getDefaultACLs(Archive *fout)
                              10570                 :                : {
 3575 tgl@sss.pgh.pa.us       10571                 :            189 :     DumpOptions *dopt = fout->dopt;
                              10572                 :                :     DefaultACLInfo *daclinfo;
                              10573                 :                :     PQExpBuffer query;
                              10574                 :                :     PGresult   *res;
                              10575                 :                :     int         i_oid;
                              10576                 :                :     int         i_tableoid;
                              10577                 :                :     int         i_defaclrole;
                              10578                 :                :     int         i_defaclnamespace;
                              10579                 :                :     int         i_defaclobjtype;
                              10580                 :                :     int         i_defaclacl;
                              10581                 :                :     int         i_acldefault;
                              10582                 :                :     int         i,
                              10583                 :                :                 ntups;
                              10584                 :                : 
 5866                         10585                 :            189 :     query = createPQExpBuffer();
                              10586                 :                : 
                              10587                 :                :     /*
                              10588                 :                :      * Global entries (with defaclnamespace=0) replace the hard-wired default
                              10589                 :                :      * ACL for their object type.  We should dump them as deltas from the
                              10590                 :                :      * default ACL, since that will be used as a starting point for
                              10591                 :                :      * interpreting the ALTER DEFAULT PRIVILEGES commands.  On the other hand,
                              10592                 :                :      * non-global entries can only add privileges not revoke them.  We must
                              10593                 :                :      * dump those as-is (i.e., as deltas from an empty ACL).
                              10594                 :                :      *
                              10595                 :                :      * We can use defaclobjtype as the object type for acldefault(), except
                              10596                 :                :      * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
                              10597                 :                :      * 's'.
                              10598                 :                :      */
 1147 drowley@postgresql.o    10599                 :            189 :     appendPQExpBufferStr(query,
                              10600                 :                :                          "SELECT oid, tableoid, "
                              10601                 :                :                          "defaclrole, "
                              10602                 :                :                          "defaclnamespace, "
                              10603                 :                :                          "defaclobjtype, "
                              10604                 :                :                          "defaclacl, "
                              10605                 :                :                          "CASE WHEN defaclnamespace = 0 THEN "
                              10606                 :                :                          "acldefault(CASE WHEN defaclobjtype = 'S' "
                              10607                 :                :                          "THEN 's'::\"char\" ELSE defaclobjtype END, "
                              10608                 :                :                          "defaclrole) ELSE '{}' END AS acldefault "
                              10609                 :                :                          "FROM pg_default_acl");
                              10610                 :                : 
 5011 rhaas@postgresql.org    10611                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10612                 :                : 
 5866 tgl@sss.pgh.pa.us       10613                 :            189 :     ntups = PQntuples(res);
                              10614                 :                : 
 5085 bruce@momjian.us        10615                 :            189 :     daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
                              10616                 :                : 
 5866 tgl@sss.pgh.pa.us       10617                 :            189 :     i_oid = PQfnumber(res, "oid");
                              10618                 :            189 :     i_tableoid = PQfnumber(res, "tableoid");
                              10619                 :            189 :     i_defaclrole = PQfnumber(res, "defaclrole");
                              10620                 :            189 :     i_defaclnamespace = PQfnumber(res, "defaclnamespace");
                              10621                 :            189 :     i_defaclobjtype = PQfnumber(res, "defaclobjtype");
                              10622                 :            189 :     i_defaclacl = PQfnumber(res, "defaclacl");
 1421                         10623                 :            189 :     i_acldefault = PQfnumber(res, "acldefault");
                              10624                 :                : 
 5866                         10625         [ +  + ]:            383 :     for (i = 0; i < ntups; i++)
                              10626                 :                :     {
 5722 bruce@momjian.us        10627                 :            194 :         Oid         nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
                              10628                 :                : 
 5866 tgl@sss.pgh.pa.us       10629                 :            194 :         daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
                              10630                 :            194 :         daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10631                 :            194 :         daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10632                 :            194 :         AssignDumpId(&daclinfo[i].dobj);
                              10633                 :                :         /* cheesy ... is it worth coming up with a better object name? */
 5085 bruce@momjian.us        10634                 :            194 :         daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
                              10635                 :                : 
 5866 tgl@sss.pgh.pa.us       10636         [ +  + ]:            194 :         if (nspid != InvalidOid)
 1889 peter@eisentraut.org    10637                 :             90 :             daclinfo[i].dobj.namespace = findNamespace(nspid);
                              10638                 :                :         else
 5866 tgl@sss.pgh.pa.us       10639                 :            104 :             daclinfo[i].dobj.namespace = NULL;
                              10640                 :                : 
 1421                         10641                 :            194 :         daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
                              10642                 :            194 :         daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10643                 :            194 :         daclinfo[i].dacl.privtype = 0;
                              10644                 :            194 :         daclinfo[i].dacl.initprivs = NULL;
 1396                         10645                 :            194 :         daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
 5866                         10646                 :            194 :         daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
                              10647                 :                : 
                              10648                 :                :         /* Default ACLs are ACLs, of course */
 1421                         10649                 :            194 :         daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10650                 :                : 
                              10651                 :                :         /* Decide whether we want to dump it */
 3575                         10652                 :            194 :         selectDumpableDefaultACL(&(daclinfo[i]), dopt);
                              10653                 :                :     }
                              10654                 :                : 
 5866                         10655                 :            189 :     PQclear(res);
                              10656                 :                : 
                              10657                 :            189 :     destroyPQExpBuffer(query);
                              10658                 :            189 : }
                              10659                 :                : 
                              10660                 :                : /*
                              10661                 :                :  * getRoleName -- look up the name of a role, given its OID
                              10662                 :                :  *
                              10663                 :                :  * In current usage, we don't expect failures, so error out for a bad OID.
                              10664                 :                :  */
                              10665                 :                : static const char *
 1396                         10666                 :         729911 : getRoleName(const char *roleoid_str)
                              10667                 :                : {
                              10668                 :         729911 :     Oid         roleoid = atooid(roleoid_str);
                              10669                 :                : 
                              10670                 :                :     /*
                              10671                 :                :      * Do binary search to find the appropriate item.
                              10672                 :                :      */
                              10673         [ +  - ]:         729911 :     if (nrolenames > 0)
                              10674                 :                :     {
                              10675                 :         729911 :         RoleNameItem *low = &rolenames[0];
                              10676                 :         729911 :         RoleNameItem *high = &rolenames[nrolenames - 1];
                              10677                 :                : 
                              10678         [ +  - ]:        2919360 :         while (low <= high)
                              10679                 :                :         {
                              10680                 :        2919360 :             RoleNameItem *middle = low + (high - low) / 2;
                              10681                 :                : 
                              10682         [ +  + ]:        2919360 :             if (roleoid < middle->roleoid)
                              10683                 :        2188566 :                 high = middle - 1;
                              10684         [ +  + ]:         730794 :             else if (roleoid > middle->roleoid)
                              10685                 :            883 :                 low = middle + 1;
                              10686                 :                :             else
                              10687                 :         729911 :                 return middle->rolename; /* found a match */
                              10688                 :                :         }
                              10689                 :                :     }
                              10690                 :                : 
 1298 tgl@sss.pgh.pa.us       10691                 :UBC           0 :     pg_fatal("role with OID %u does not exist", roleoid);
                              10692                 :                :     return NULL;                /* keep compiler quiet */
                              10693                 :                : }
                              10694                 :                : 
                              10695                 :                : /*
                              10696                 :                :  * collectRoleNames --
                              10697                 :                :  *
                              10698                 :                :  * Construct a table of all known roles.
                              10699                 :                :  * The table is sorted by OID for speed in lookup.
                              10700                 :                :  */
                              10701                 :                : static void
 1396 tgl@sss.pgh.pa.us       10702                 :CBC         190 : collectRoleNames(Archive *fout)
                              10703                 :                : {
                              10704                 :                :     PGresult   *res;
                              10705                 :                :     const char *query;
                              10706                 :                :     int         i;
                              10707                 :                : 
                              10708                 :            190 :     query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
                              10709                 :                : 
                              10710                 :            190 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                              10711                 :                : 
                              10712                 :            190 :     nrolenames = PQntuples(res);
                              10713                 :                : 
                              10714                 :            190 :     rolenames = (RoleNameItem *) pg_malloc(nrolenames * sizeof(RoleNameItem));
                              10715                 :                : 
                              10716         [ +  + ]:           3725 :     for (i = 0; i < nrolenames; i++)
                              10717                 :                :     {
                              10718                 :           3535 :         rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
                              10719                 :           3535 :         rolenames[i].rolename = pg_strdup(PQgetvalue(res, i, 1));
                              10720                 :                :     }
                              10721                 :                : 
                              10722                 :            190 :     PQclear(res);
                              10723                 :            190 : }
                              10724                 :                : 
                              10725                 :                : /*
                              10726                 :                :  * getAdditionalACLs
                              10727                 :                :  *
                              10728                 :                :  * We have now created all the DumpableObjects, and collected the ACL data
                              10729                 :                :  * that appears in the directly-associated catalog entries.  However, there's
                              10730                 :                :  * more ACL-related info to collect.  If any of a table's columns have ACLs,
                              10731                 :                :  * we must set the TableInfo's DUMP_COMPONENT_ACL components flag, as well as
                              10732                 :                :  * its hascolumnACLs flag (we won't store the ACLs themselves here, though).
                              10733                 :                :  * Also, in versions having the pg_init_privs catalog, read that and load the
                              10734                 :                :  * information into the relevant DumpableObjects.
                              10735                 :                :  */
                              10736                 :                : static void
 1421                         10737                 :            187 : getAdditionalACLs(Archive *fout)
                              10738                 :                : {
                              10739                 :            187 :     PQExpBuffer query = createPQExpBuffer();
                              10740                 :                :     PGresult   *res;
                              10741                 :                :     int         ntups,
                              10742                 :                :                 i;
                              10743                 :                : 
                              10744                 :                :     /* Check for per-column ACLs */
 1413                         10745                 :            187 :     appendPQExpBufferStr(query,
                              10746                 :                :                          "SELECT DISTINCT attrelid FROM pg_attribute "
                              10747                 :                :                          "WHERE attacl IS NOT NULL");
                              10748                 :                : 
                              10749                 :            187 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10750                 :                : 
                              10751                 :            187 :     ntups = PQntuples(res);
                              10752         [ +  + ]:            544 :     for (i = 0; i < ntups; i++)
                              10753                 :                :     {
                              10754                 :            357 :         Oid         relid = atooid(PQgetvalue(res, i, 0));
                              10755                 :                :         TableInfo  *tblinfo;
                              10756                 :                : 
                              10757                 :            357 :         tblinfo = findTableByOid(relid);
                              10758                 :                :         /* OK to ignore tables we haven't got a DumpableObject for */
                              10759         [ +  - ]:            357 :         if (tblinfo)
                              10760                 :                :         {
                              10761                 :            357 :             tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
                              10762                 :            357 :             tblinfo->hascolumnACLs = true;
                              10763                 :                :         }
                              10764                 :                :     }
                              10765                 :            187 :     PQclear(res);
                              10766                 :                : 
                              10767                 :                :     /* Fetch initial-privileges data */
 1421                         10768         [ +  - ]:            187 :     if (fout->remoteVersion >= 90600)
                              10769                 :                :     {
                              10770                 :            187 :         printfPQExpBuffer(query,
                              10771                 :                :                           "SELECT objoid, classoid, objsubid, privtype, initprivs "
                              10772                 :                :                           "FROM pg_init_privs");
                              10773                 :                : 
                              10774                 :            187 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10775                 :                : 
                              10776                 :            187 :         ntups = PQntuples(res);
                              10777         [ +  + ]:          44440 :         for (i = 0; i < ntups; i++)
                              10778                 :                :         {
                              10779                 :          44253 :             Oid         objoid = atooid(PQgetvalue(res, i, 0));
                              10780                 :          44253 :             Oid         classoid = atooid(PQgetvalue(res, i, 1));
                              10781                 :          44253 :             int         objsubid = atoi(PQgetvalue(res, i, 2));
                              10782                 :          44253 :             char        privtype = *(PQgetvalue(res, i, 3));
                              10783                 :          44253 :             char       *initprivs = PQgetvalue(res, i, 4);
                              10784                 :                :             CatalogId   objId;
                              10785                 :                :             DumpableObject *dobj;
                              10786                 :                : 
                              10787                 :          44253 :             objId.tableoid = classoid;
                              10788                 :          44253 :             objId.oid = objoid;
                              10789                 :          44253 :             dobj = findObjectByCatalogId(objId);
                              10790                 :                :             /* OK to ignore entries we haven't got a DumpableObject for */
                              10791         [ +  + ]:          44253 :             if (dobj)
                              10792                 :                :             {
                              10793                 :                :                 /* Cope with sub-object initprivs */
                              10794         [ +  + ]:          31768 :                 if (objsubid != 0)
                              10795                 :                :                 {
                              10796         [ +  - ]:           3764 :                     if (dobj->objType == DO_TABLE)
                              10797                 :                :                     {
                              10798                 :                :                         /* For a column initprivs, set the table's ACL flags */
                              10799                 :           3764 :                         dobj->components |= DUMP_COMPONENT_ACL;
                              10800                 :           3764 :                         ((TableInfo *) dobj)->hascolumnACLs = true;
                              10801                 :                :                     }
                              10802                 :                :                     else
 1421 tgl@sss.pgh.pa.us       10803                 :UBC           0 :                         pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10804                 :                :                                        classoid, objoid, objsubid);
 1421 tgl@sss.pgh.pa.us       10805                 :CBC        3947 :                     continue;
                              10806                 :                :                 }
                              10807                 :                : 
                              10808                 :                :                 /*
                              10809                 :                :                  * We ignore any pg_init_privs.initprivs entry for the public
                              10810                 :                :                  * schema, as explained in getNamespaces().
                              10811                 :                :                  */
                              10812         [ +  + ]:          28004 :                 if (dobj->objType == DO_NAMESPACE &&
                              10813         [ +  + ]:            370 :                     strcmp(dobj->name, "public") == 0)
                              10814                 :            183 :                     continue;
                              10815                 :                : 
                              10816                 :                :                 /* Else it had better be of a type we think has ACLs */
                              10817         [ +  + ]:          27821 :                 if (dobj->objType == DO_NAMESPACE ||
                              10818         [ +  + ]:          27634 :                     dobj->objType == DO_TYPE ||
                              10819         [ +  + ]:          27610 :                     dobj->objType == DO_FUNC ||
                              10820         [ +  + ]:          27518 :                     dobj->objType == DO_AGG ||
                              10821         [ -  + ]:          27494 :                     dobj->objType == DO_TABLE ||
 1421 tgl@sss.pgh.pa.us       10822         [ #  # ]:UBC           0 :                     dobj->objType == DO_PROCLANG ||
                              10823         [ #  # ]:              0 :                     dobj->objType == DO_FDW ||
                              10824         [ #  # ]:              0 :                     dobj->objType == DO_FOREIGN_SERVER)
 1421 tgl@sss.pgh.pa.us       10825                 :CBC       27821 :                 {
                              10826                 :          27821 :                     DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
                              10827                 :                : 
                              10828                 :          27821 :                     daobj->dacl.privtype = privtype;
                              10829                 :          27821 :                     daobj->dacl.initprivs = pstrdup(initprivs);
                              10830                 :                :                 }
                              10831                 :                :                 else
 1421 tgl@sss.pgh.pa.us       10832                 :UBC           0 :                     pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10833                 :                :                                    classoid, objoid, objsubid);
                              10834                 :                :             }
                              10835                 :                :         }
 1421 tgl@sss.pgh.pa.us       10836                 :CBC         187 :         PQclear(res);
                              10837                 :                :     }
                              10838                 :                : 
                              10839                 :            187 :     destroyPQExpBuffer(query);
                              10840                 :            187 : }
                              10841                 :                : 
                              10842                 :                : /*
                              10843                 :                :  * dumpCommentExtended --
                              10844                 :                :  *
                              10845                 :                :  * This routine is used to dump any comments associated with the
                              10846                 :                :  * object handed to this routine. The routine takes the object type
                              10847                 :                :  * and object name (ready to print, except for schema decoration), plus
                              10848                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              10849                 :                :  * plus catalog ID and subid which are the lookup key for pg_description,
                              10850                 :                :  * plus the dump ID for the object (for setting a dependency).
                              10851                 :                :  * If a matching pg_description entry is found, it is dumped.
                              10852                 :                :  *
                              10853                 :                :  * Note: in some cases, such as comments for triggers and rules, the "type"
                              10854                 :                :  * string really looks like, e.g., "TRIGGER name ON".  This is a bit of a hack
                              10855                 :                :  * but it doesn't seem worth complicating the API for all callers to make
                              10856                 :                :  * it cleaner.
                              10857                 :                :  *
                              10858                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              10859                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              10860                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              10861                 :                :  * ordering of the comment in the dump file, because this routine is called
                              10862                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              10863                 :                :  * calling ArchiveEntry() for the specified object.
                              10864                 :                :  */
                              10865                 :                : static void
 1582 noah@leadboat.com       10866                 :           6607 : dumpCommentExtended(Archive *fout, const char *type,
                              10867                 :                :                     const char *name, const char *namespace,
                              10868                 :                :                     const char *owner, CatalogId catalogId,
                              10869                 :                :                     int subid, DumpId dumpId,
                              10870                 :                :                     const char *initdb_comment)
                              10871                 :                : {
 3575 tgl@sss.pgh.pa.us       10872                 :           6607 :     DumpOptions *dopt = fout->dopt;
                              10873                 :                :     CommentItem *comments;
                              10874                 :                :     int         ncomments;
                              10875                 :                : 
                              10876                 :                :     /* do nothing, if --no-comments is supplied */
 2832                         10877         [ -  + ]:           6607 :     if (dopt->no_comments)
 2832 tgl@sss.pgh.pa.us       10878                 :UBC           0 :         return;
                              10879                 :                : 
                              10880                 :                :     /* Comments are schema not data ... except LO comments are data */
 2800 tgl@sss.pgh.pa.us       10881         [ +  + ]:CBC        6607 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              10882                 :                :     {
  336 nathan@postgresql.or    10883         [ -  + ]:           6548 :         if (!dopt->dumpSchema)
 5730 tgl@sss.pgh.pa.us       10884                 :UBC           0 :             return;
                              10885                 :                :     }
                              10886                 :                :     else
                              10887                 :                :     {
                              10888                 :                :         /* We do dump LO comments in binary-upgrade mode */
  336 nathan@postgresql.or    10889   [ +  +  -  + ]:CBC          59 :         if (!dopt->dumpData && !dopt->binary_upgrade)
 5730 tgl@sss.pgh.pa.us       10890                 :UBC           0 :             return;
                              10891                 :                :     }
                              10892                 :                : 
                              10893                 :                :     /* Search for comments associated with catalogId, using table */
 1397 tgl@sss.pgh.pa.us       10894                 :CBC        6607 :     ncomments = findComments(catalogId.tableoid, catalogId.oid,
                              10895                 :                :                              &comments);
                              10896                 :                : 
                              10897                 :                :     /* Is there one matching the subid? */
 7891                         10898         [ +  + ]:           6607 :     while (ncomments > 0)
                              10899                 :                :     {
                              10900         [ +  - ]:           6561 :         if (comments->objsubid == subid)
                              10901                 :           6561 :             break;
 7891 tgl@sss.pgh.pa.us       10902                 :UBC           0 :         comments++;
                              10903                 :              0 :         ncomments--;
                              10904                 :                :     }
                              10905                 :                : 
 1582 noah@leadboat.com       10906         [ +  + ]:CBC        6607 :     if (initdb_comment != NULL)
                              10907                 :                :     {
                              10908                 :                :         static CommentItem empty_comment = {.descr = ""};
                              10909                 :                : 
                              10910                 :                :         /*
                              10911                 :                :          * initdb creates this object with a comment.  Skip dumping the
                              10912                 :                :          * initdb-provided comment, which would complicate matters for
                              10913                 :                :          * non-superuser use of pg_dump.  When the DBA has removed initdb's
                              10914                 :                :          * comment, replicate that.
                              10915                 :                :          */
                              10916         [ +  + ]:            120 :         if (ncomments == 0)
                              10917                 :                :         {
                              10918                 :              4 :             comments = &empty_comment;
                              10919                 :              4 :             ncomments = 1;
                              10920                 :                :         }
                              10921         [ +  - ]:            116 :         else if (strcmp(comments->descr, initdb_comment) == 0)
                              10922                 :            116 :             ncomments = 0;
                              10923                 :                :     }
                              10924                 :                : 
                              10925                 :                :     /* If a comment exists, build COMMENT ON statement */
 7891 tgl@sss.pgh.pa.us       10926         [ +  + ]:           6607 :     if (ncomments > 0)
                              10927                 :                :     {
                              10928                 :           6449 :         PQExpBuffer query = createPQExpBuffer();
 2800                         10929                 :           6449 :         PQExpBuffer tag = createPQExpBuffer();
                              10930                 :                : 
                              10931                 :           6449 :         appendPQExpBuffer(query, "COMMENT ON %s ", type);
                              10932   [ +  +  +  - ]:           6449 :         if (namespace && *namespace)
                              10933                 :           6273 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
                              10934                 :           6449 :         appendPQExpBuffer(query, "%s IS ", name);
 7092                         10935                 :           6449 :         appendStringLiteralAH(query, comments->descr, fout);
 4361 heikki.linnakangas@i    10936                 :           6449 :         appendPQExpBufferStr(query, ";\n");
                              10937                 :                : 
 2800 tgl@sss.pgh.pa.us       10938                 :           6449 :         appendPQExpBuffer(tag, "%s %s", type, name);
                              10939                 :                : 
                              10940                 :                :         /*
                              10941                 :                :          * We mark comments as SECTION_NONE because they really belong in the
                              10942                 :                :          * same section as their parent, whether that is pre-data or
                              10943                 :                :          * post-data.
                              10944                 :                :          */
 7996                         10945                 :           6449 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    10946                 :           6449 :                      ARCHIVE_OPTS(.tag = tag->data,
                              10947                 :                :                                   .namespace = namespace,
                              10948                 :                :                                   .owner = owner,
                              10949                 :                :                                   .description = "COMMENT",
                              10950                 :                :                                   .section = SECTION_NONE,
                              10951                 :                :                                   .createStmt = query->data,
                              10952                 :                :                                   .deps = &dumpId,
                              10953                 :                :                                   .nDeps = 1));
                              10954                 :                : 
 7891 tgl@sss.pgh.pa.us       10955                 :           6449 :         destroyPQExpBuffer(query);
 2800                         10956                 :           6449 :         destroyPQExpBuffer(tag);
                              10957                 :                :     }
                              10958                 :                : }
                              10959                 :                : 
                              10960                 :                : /*
                              10961                 :                :  * dumpComment --
                              10962                 :                :  *
                              10963                 :                :  * Typical simplification of the above function.
                              10964                 :                :  */
                              10965                 :                : static inline void
 1582 noah@leadboat.com       10966                 :           6448 : dumpComment(Archive *fout, const char *type,
                              10967                 :                :             const char *name, const char *namespace,
                              10968                 :                :             const char *owner, CatalogId catalogId,
                              10969                 :                :             int subid, DumpId dumpId)
                              10970                 :                : {
                              10971                 :           6448 :     dumpCommentExtended(fout, type, name, namespace, owner,
                              10972                 :                :                         catalogId, subid, dumpId, NULL);
                              10973                 :           6448 : }
                              10974                 :                : 
                              10975                 :                : /*
                              10976                 :                :  * appendNamedArgument --
                              10977                 :                :  *
                              10978                 :                :  * Convenience routine for constructing parameters of the form:
                              10979                 :                :  * 'paraname', 'value'::type
                              10980                 :                :  */
                              10981                 :                : static void
  249 jdavis@postgresql.or    10982                 :           5496 : appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
                              10983                 :                :                     const char *argtype, const char *argval)
                              10984                 :                : {
  243 tgl@sss.pgh.pa.us       10985                 :           5496 :     appendPQExpBufferStr(out, ",\n\t");
                              10986                 :                : 
  249 jdavis@postgresql.or    10987                 :           5496 :     appendStringLiteralAH(out, argname, fout);
                              10988                 :           5496 :     appendPQExpBufferStr(out, ", ");
                              10989                 :                : 
                              10990                 :           5496 :     appendStringLiteralAH(out, argval, fout);
                              10991                 :           5496 :     appendPQExpBuffer(out, "::%s", argtype);
                              10992                 :           5496 : }
                              10993                 :                : 
                              10994                 :                : /*
                              10995                 :                :  * fetchAttributeStats --
                              10996                 :                :  *
                              10997                 :                :  * Fetch next batch of attribute statistics for dumpRelationStats_dumper().
                              10998                 :                :  */
                              10999                 :                : static PGresult *
  206 nathan@postgresql.or    11000                 :           1037 : fetchAttributeStats(Archive *fout)
                              11001                 :                : {
                              11002                 :           1037 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                              11003                 :           1037 :     PQExpBuffer nspnames = createPQExpBuffer();
                              11004                 :           1037 :     PQExpBuffer relnames = createPQExpBuffer();
                              11005                 :           1037 :     int         count = 0;
                              11006                 :           1037 :     PGresult   *res = NULL;
                              11007                 :                :     static TocEntry *te;
                              11008                 :                :     static bool restarted;
                              11009                 :           1037 :     int         max_rels = MAX_ATTR_STATS_RELS;
                              11010                 :                : 
                              11011                 :                :     /*
                              11012                 :                :      * Our query for retrieving statistics for multiple relations uses WITH
                              11013                 :                :      * ORDINALITY and multi-argument UNNEST(), both of which were introduced
                              11014                 :                :      * in v9.4.  For older versions, we resort to gathering statistics for a
                              11015                 :                :      * single relation at a time.
                              11016                 :                :      */
                              11017         [ -  + ]:           1037 :     if (fout->remoteVersion < 90400)
  206 nathan@postgresql.or    11018                 :UBC           0 :         max_rels = 1;
                              11019                 :                : 
                              11020                 :                :     /* If we're just starting, set our TOC pointer. */
  206 nathan@postgresql.or    11021         [ +  + ]:CBC        1037 :     if (!te)
                              11022                 :             64 :         te = AH->toc->next;
                              11023                 :                : 
                              11024                 :                :     /*
                              11025                 :                :      * We can't easily avoid a second TOC scan for the tar format because it
                              11026                 :                :      * writes restore.sql separately, which means we must execute the queries
                              11027                 :                :      * twice.  This feels risky, but there is no known reason it should
                              11028                 :                :      * generate different output than the first pass.  Even if it does, the
                              11029                 :                :      * worst-case scenario is that restore.sql might have different statistics
                              11030                 :                :      * data than the archive.
                              11031                 :                :      */
                              11032   [ +  +  +  +  :           1037 :     if (!restarted && te == AH->toc && AH->format == archTar)
                                              +  + ]
                              11033                 :                :     {
                              11034                 :              1 :         te = AH->toc->next;
                              11035                 :              1 :         restarted = true;
                              11036                 :                :     }
                              11037                 :                : 
  160                         11038                 :           1037 :     appendPQExpBufferChar(nspnames, '{');
                              11039                 :           1037 :     appendPQExpBufferChar(relnames, '{');
                              11040                 :                : 
                              11041                 :                :     /*
                              11042                 :                :      * Scan the TOC for the next set of relevant stats entries.  We assume
                              11043                 :                :      * that statistics are dumped in the order they are listed in the TOC.
                              11044                 :                :      * This is perhaps not the sturdiest assumption, so we verify it matches
                              11045                 :                :      * reality in dumpRelationStats_dumper().
                              11046                 :                :      */
  206                         11047   [ +  +  +  + ]:          15668 :     for (; te != AH->toc && count < max_rels; te = te->next)
                              11048                 :                :     {
                              11049         [ +  + ]:          14631 :         if ((te->reqs & REQ_STATS) != 0 &&
                              11050         [ +  - ]:           3226 :             strcmp(te->desc, "STATISTICS DATA") == 0)
                              11051                 :                :         {
  160                         11052                 :           3226 :             appendPGArray(nspnames, te->namespace);
                              11053                 :           3226 :             appendPGArray(relnames, te->tag);
  206                         11054                 :           3226 :             count++;
                              11055                 :                :         }
                              11056                 :                :     }
                              11057                 :                : 
  160                         11058                 :           1037 :     appendPQExpBufferChar(nspnames, '}');
                              11059                 :           1037 :     appendPQExpBufferChar(relnames, '}');
                              11060                 :                : 
                              11061                 :                :     /* Execute the query for the next batch of relations. */
  206                         11062         [ +  + ]:           1037 :     if (count > 0)
                              11063                 :                :     {
                              11064                 :            107 :         PQExpBuffer query = createPQExpBuffer();
                              11065                 :                : 
  160                         11066                 :            107 :         appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
                              11067                 :            107 :         appendStringLiteralAH(query, nspnames->data, fout);
                              11068                 :            107 :         appendPQExpBufferStr(query, "::pg_catalog.name[],");
                              11069                 :            107 :         appendStringLiteralAH(query, relnames->data, fout);
                              11070                 :            107 :         appendPQExpBufferStr(query, "::pg_catalog.name[])");
  206                         11071                 :            107 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11072                 :            107 :         destroyPQExpBuffer(query);
                              11073                 :                :     }
                              11074                 :                : 
                              11075                 :           1037 :     destroyPQExpBuffer(nspnames);
                              11076                 :           1037 :     destroyPQExpBuffer(relnames);
                              11077                 :           1037 :     return res;
                              11078                 :                : }
                              11079                 :                : 
                              11080                 :                : /*
                              11081                 :                :  * dumpRelationStats_dumper --
                              11082                 :                :  *
                              11083                 :                :  * Generate command to import stats into the relation on the new database.
                              11084                 :                :  * This routine is called by the Archiver when it wants the statistics to be
                              11085                 :                :  * dumped.
                              11086                 :                :  */
                              11087                 :                : static char *
                              11088                 :           3226 : dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
                              11089                 :                : {
                              11090                 :           3226 :     const RelStatsInfo *rsinfo = (RelStatsInfo *) userArg;
                              11091                 :                :     static PGresult *res;
                              11092                 :                :     static int  rownum;
                              11093                 :                :     PQExpBuffer query;
                              11094                 :                :     PQExpBufferData out_data;
                              11095                 :           3226 :     PQExpBuffer out = &out_data;
                              11096                 :                :     int         i_schemaname;
                              11097                 :                :     int         i_tablename;
                              11098                 :                :     int         i_attname;
                              11099                 :                :     int         i_inherited;
                              11100                 :                :     int         i_null_frac;
                              11101                 :                :     int         i_avg_width;
                              11102                 :                :     int         i_n_distinct;
                              11103                 :                :     int         i_most_common_vals;
                              11104                 :                :     int         i_most_common_freqs;
                              11105                 :                :     int         i_histogram_bounds;
                              11106                 :                :     int         i_correlation;
                              11107                 :                :     int         i_most_common_elems;
                              11108                 :                :     int         i_most_common_elem_freqs;
                              11109                 :                :     int         i_elem_count_histogram;
                              11110                 :                :     int         i_range_length_histogram;
                              11111                 :                :     int         i_range_empty_frac;
                              11112                 :                :     int         i_range_bounds_histogram;
                              11113                 :                :     static TocEntry *expected_te;
                              11114                 :                : 
                              11115                 :                :     /*
                              11116                 :                :      * fetchAttributeStats() assumes that the statistics are dumped in the
                              11117                 :                :      * order they are listed in the TOC.  We verify that here for safety.
                              11118                 :                :      */
                              11119         [ +  + ]:           3226 :     if (!expected_te)
                              11120                 :             64 :         expected_te = ((ArchiveHandle *) fout)->toc;
                              11121                 :                : 
                              11122                 :           3226 :     expected_te = expected_te->next;
                              11123         [ +  + ]:          12863 :     while ((expected_te->reqs & REQ_STATS) == 0 ||
                              11124         [ -  + ]:           3226 :            strcmp(expected_te->desc, "STATISTICS DATA") != 0)
                              11125                 :           9637 :         expected_te = expected_te->next;
                              11126                 :                : 
                              11127         [ -  + ]:           3226 :     if (te != expected_te)
  133 peter@eisentraut.org    11128                 :UBC           0 :         pg_fatal("statistics dumped out of order (current: %d %s %s, expected: %d %s %s)",
                              11129                 :                :                  te->dumpId, te->desc, te->tag,
                              11130                 :                :                  expected_te->dumpId, expected_te->desc, expected_te->tag);
                              11131                 :                : 
  244 jdavis@postgresql.or    11132                 :CBC        3226 :     query = createPQExpBuffer();
                              11133         [ +  + ]:           3226 :     if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
                              11134                 :                :     {
                              11135                 :             64 :         appendPQExpBufferStr(query,
                              11136                 :                :                              "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
                              11137                 :                :                              "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
                              11138                 :                :                              "s.null_frac, s.avg_width, s.n_distinct, "
                              11139                 :                :                              "s.most_common_vals, s.most_common_freqs, "
                              11140                 :                :                              "s.histogram_bounds, s.correlation, "
                              11141                 :                :                              "s.most_common_elems, s.most_common_elem_freqs, "
                              11142                 :                :                              "s.elem_count_histogram, ");
                              11143                 :                : 
                              11144         [ +  - ]:             64 :         if (fout->remoteVersion >= 170000)
                              11145                 :             64 :             appendPQExpBufferStr(query,
                              11146                 :                :                                  "s.range_length_histogram, "
                              11147                 :                :                                  "s.range_empty_frac, "
                              11148                 :                :                                  "s.range_bounds_histogram ");
                              11149                 :                :         else
  244 jdavis@postgresql.or    11150                 :UBC           0 :             appendPQExpBufferStr(query,
                              11151                 :                :                                  "NULL AS range_length_histogram,"
                              11152                 :                :                                  "NULL AS range_empty_frac,"
                              11153                 :                :                                  "NULL AS range_bounds_histogram ");
                              11154                 :                : 
                              11155                 :                :         /*
                              11156                 :                :          * The results must be in the order of the relations supplied in the
                              11157                 :                :          * parameters to ensure we remain in sync as we walk through the TOC.
                              11158                 :                :          * The redundant filter clause on s.tablename = ANY(...) seems
                              11159                 :                :          * sufficient to convince the planner to use
                              11160                 :                :          * pg_class_relname_nsp_index, which avoids a full scan of pg_stats.
                              11161                 :                :          * This may not work for all versions.
                              11162                 :                :          *
                              11163                 :                :          * Our query for retrieving statistics for multiple relations uses
                              11164                 :                :          * WITH ORDINALITY and multi-argument UNNEST(), both of which were
                              11165                 :                :          * introduced in v9.4.  For older versions, we resort to gathering
                              11166                 :                :          * statistics for a single relation at a time.
                              11167                 :                :          */
  206 nathan@postgresql.or    11168         [ +  - ]:CBC          64 :         if (fout->remoteVersion >= 90400)
                              11169                 :             64 :             appendPQExpBufferStr(query,
                              11170                 :                :                                  "FROM pg_catalog.pg_stats s "
                              11171                 :                :                                  "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) "
                              11172                 :                :                                  "ON s.schemaname = u.schemaname "
                              11173                 :                :                                  "AND s.tablename = u.tablename "
                              11174                 :                :                                  "WHERE s.tablename = ANY($2) "
                              11175                 :                :                                  "ORDER BY u.ord, s.attname, s.inherited");
                              11176                 :                :         else
  206 nathan@postgresql.or    11177                 :UBC           0 :             appendPQExpBufferStr(query,
                              11178                 :                :                                  "FROM pg_catalog.pg_stats s "
                              11179                 :                :                                  "WHERE s.schemaname = $1[1] "
                              11180                 :                :                                  "AND s.tablename = $2[1] "
                              11181                 :                :                                  "ORDER BY s.attname, s.inherited");
                              11182                 :                : 
  244 jdavis@postgresql.or    11183                 :CBC          64 :         ExecuteSqlStatement(fout, query->data);
                              11184                 :                : 
                              11185                 :             64 :         fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS] = true;
                              11186                 :             64 :         resetPQExpBuffer(query);
                              11187                 :                :     }
                              11188                 :                : 
  206 nathan@postgresql.or    11189                 :           3226 :     initPQExpBuffer(out);
                              11190                 :                : 
                              11191                 :                :     /* restore relation stats */
  243 tgl@sss.pgh.pa.us       11192                 :           3226 :     appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
  200 peter@eisentraut.org    11193                 :           3226 :     appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
                              11194                 :                :                       fout->remoteVersion);
  216 jdavis@postgresql.or    11195                 :           3226 :     appendPQExpBufferStr(out, "\t'schemaname', ");
                              11196                 :           3226 :     appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
                              11197                 :           3226 :     appendPQExpBufferStr(out, ",\n");
                              11198                 :           3226 :     appendPQExpBufferStr(out, "\t'relname', ");
                              11199                 :           3226 :     appendStringLiteralAH(out, rsinfo->dobj.name, fout);
                              11200                 :           3226 :     appendPQExpBufferStr(out, ",\n");
  243 tgl@sss.pgh.pa.us       11201                 :           3226 :     appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
                              11202                 :                : 
                              11203                 :                :     /*
                              11204                 :                :      * Before v14, a reltuples value of 0 was ambiguous: it could either mean
                              11205                 :                :      * the relation is empty, or it could mean that it hadn't yet been
                              11206                 :                :      * vacuumed or analyzed.  (Newer versions use -1 for the latter case.)
                              11207                 :                :      * This ambiguity allegedly can cause the planner to choose inefficient
                              11208                 :                :      * plans after restoring to v18 or newer.  To deal with this, let's just
                              11209                 :                :      * set reltuples to -1 in that case.
                              11210                 :                :      */
  158 nathan@postgresql.or    11211   [ -  +  -  - ]:           3226 :     if (fout->remoteVersion < 140000 && strcmp("0", rsinfo->reltuples) == 0)
  158 nathan@postgresql.or    11212                 :UBC           0 :         appendPQExpBufferStr(out, "\t'reltuples', '-1'::real,\n");
                              11213                 :                :     else
  158 nathan@postgresql.or    11214                 :CBC        3226 :         appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples);
                              11215                 :                : 
  211 jdavis@postgresql.or    11216                 :           3226 :     appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer",
  243 tgl@sss.pgh.pa.us       11217                 :           3226 :                       rsinfo->relallvisible);
                              11218                 :                : 
  211 jdavis@postgresql.or    11219         [ +  - ]:           3226 :     if (fout->remoteVersion >= 180000)
                              11220                 :           3226 :         appendPQExpBuffer(out, ",\n\t'relallfrozen', '%d'::integer", rsinfo->relallfrozen);
                              11221                 :                : 
                              11222                 :           3226 :     appendPQExpBufferStr(out, "\n);\n");
                              11223                 :                : 
                              11224                 :                :     /* Fetch the next batch of attribute statistics if needed. */
  206 nathan@postgresql.or    11225         [ +  + ]:           3226 :     if (rownum >= PQntuples(res))
                              11226                 :                :     {
                              11227                 :           1037 :         PQclear(res);
                              11228                 :           1037 :         res = fetchAttributeStats(fout);
                              11229                 :           1037 :         rownum = 0;
                              11230                 :                :     }
                              11231                 :                : 
                              11232                 :           3226 :     i_schemaname = PQfnumber(res, "schemaname");
                              11233                 :           3226 :     i_tablename = PQfnumber(res, "tablename");
  243 tgl@sss.pgh.pa.us       11234                 :           3226 :     i_attname = PQfnumber(res, "attname");
                              11235                 :           3226 :     i_inherited = PQfnumber(res, "inherited");
                              11236                 :           3226 :     i_null_frac = PQfnumber(res, "null_frac");
                              11237                 :           3226 :     i_avg_width = PQfnumber(res, "avg_width");
                              11238                 :           3226 :     i_n_distinct = PQfnumber(res, "n_distinct");
                              11239                 :           3226 :     i_most_common_vals = PQfnumber(res, "most_common_vals");
                              11240                 :           3226 :     i_most_common_freqs = PQfnumber(res, "most_common_freqs");
                              11241                 :           3226 :     i_histogram_bounds = PQfnumber(res, "histogram_bounds");
                              11242                 :           3226 :     i_correlation = PQfnumber(res, "correlation");
                              11243                 :           3226 :     i_most_common_elems = PQfnumber(res, "most_common_elems");
                              11244                 :           3226 :     i_most_common_elem_freqs = PQfnumber(res, "most_common_elem_freqs");
                              11245                 :           3226 :     i_elem_count_histogram = PQfnumber(res, "elem_count_histogram");
                              11246                 :           3226 :     i_range_length_histogram = PQfnumber(res, "range_length_histogram");
                              11247                 :           3226 :     i_range_empty_frac = PQfnumber(res, "range_empty_frac");
                              11248                 :           3226 :     i_range_bounds_histogram = PQfnumber(res, "range_bounds_histogram");
                              11249                 :                : 
                              11250                 :                :     /* restore attribute stats */
  206 nathan@postgresql.or    11251         [ +  + ]:           4053 :     for (; rownum < PQntuples(res); rownum++)
                              11252                 :                :     {
                              11253                 :                :         const char *attname;
                              11254                 :                : 
                              11255                 :                :         /* Stop if the next stat row in our cache isn't for this relation. */
                              11256         [ +  + ]:           3016 :         if (strcmp(te->tag, PQgetvalue(res, rownum, i_tablename)) != 0 ||
                              11257         [ +  - ]:            827 :             strcmp(te->namespace, PQgetvalue(res, rownum, i_schemaname)) != 0)
                              11258                 :                :             break;
                              11259                 :                : 
  243 tgl@sss.pgh.pa.us       11260                 :            827 :         appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
  200 peter@eisentraut.org    11261                 :            827 :         appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
                              11262                 :                :                           fout->remoteVersion);
  216 jdavis@postgresql.or    11263                 :            827 :         appendPQExpBufferStr(out, "\t'schemaname', ");
                              11264                 :            827 :         appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
                              11265                 :            827 :         appendPQExpBufferStr(out, ",\n\t'relname', ");
                              11266                 :            827 :         appendStringLiteralAH(out, rsinfo->dobj.name, fout);
                              11267                 :                : 
  243 tgl@sss.pgh.pa.us       11268         [ -  + ]:            827 :         if (PQgetisnull(res, rownum, i_attname))
  133 peter@eisentraut.org    11269                 :UBC           0 :             pg_fatal("unexpected null attname");
  243 tgl@sss.pgh.pa.us       11270                 :CBC         827 :         attname = PQgetvalue(res, rownum, i_attname);
                              11271                 :                : 
                              11272                 :                :         /*
                              11273                 :                :          * Indexes look up attname in indAttNames to derive attnum, all others
                              11274                 :                :          * use attname directly.  We must specify attnum for indexes, since
                              11275                 :                :          * their attnames are not necessarily stable across dump/reload.
                              11276                 :                :          */
                              11277         [ +  + ]:            827 :         if (rsinfo->nindAttNames == 0)
                              11278                 :                :         {
  193 drowley@postgresql.o    11279                 :            792 :             appendPQExpBufferStr(out, ",\n\t'attname', ");
  216 jdavis@postgresql.or    11280                 :            792 :             appendStringLiteralAH(out, attname, fout);
                              11281                 :                :         }
                              11282                 :                :         else
                              11283                 :                :         {
  243 tgl@sss.pgh.pa.us       11284                 :             35 :             bool        found = false;
                              11285                 :                : 
                              11286         [ +  - ]:             66 :             for (int i = 0; i < rsinfo->nindAttNames; i++)
                              11287                 :                :             {
                              11288         [ +  + ]:             66 :                 if (strcmp(attname, rsinfo->indAttNames[i]) == 0)
                              11289                 :                :                 {
                              11290                 :             35 :                     appendPQExpBuffer(out, ",\n\t'attnum', '%d'::smallint",
                              11291                 :                :                                       i + 1);
                              11292                 :             35 :                     found = true;
                              11293                 :             35 :                     break;
                              11294                 :                :                 }
                              11295                 :                :             }
                              11296                 :                : 
                              11297         [ -  + ]:             35 :             if (!found)
  243 tgl@sss.pgh.pa.us       11298                 :UBC           0 :                 pg_fatal("could not find index attname \"%s\"", attname);
                              11299                 :                :         }
                              11300                 :                : 
  243 tgl@sss.pgh.pa.us       11301         [ +  - ]:CBC         827 :         if (!PQgetisnull(res, rownum, i_inherited))
                              11302                 :            827 :             appendNamedArgument(out, fout, "inherited", "boolean",
                              11303                 :            827 :                                 PQgetvalue(res, rownum, i_inherited));
                              11304         [ +  - ]:            827 :         if (!PQgetisnull(res, rownum, i_null_frac))
                              11305                 :            827 :             appendNamedArgument(out, fout, "null_frac", "real",
                              11306                 :            827 :                                 PQgetvalue(res, rownum, i_null_frac));
                              11307         [ +  - ]:            827 :         if (!PQgetisnull(res, rownum, i_avg_width))
                              11308                 :            827 :             appendNamedArgument(out, fout, "avg_width", "integer",
                              11309                 :            827 :                                 PQgetvalue(res, rownum, i_avg_width));
                              11310         [ +  - ]:            827 :         if (!PQgetisnull(res, rownum, i_n_distinct))
                              11311                 :            827 :             appendNamedArgument(out, fout, "n_distinct", "real",
                              11312                 :            827 :                                 PQgetvalue(res, rownum, i_n_distinct));
                              11313         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_most_common_vals))
                              11314                 :            429 :             appendNamedArgument(out, fout, "most_common_vals", "text",
                              11315                 :            429 :                                 PQgetvalue(res, rownum, i_most_common_vals));
                              11316         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_most_common_freqs))
                              11317                 :            429 :             appendNamedArgument(out, fout, "most_common_freqs", "real[]",
                              11318                 :            429 :                                 PQgetvalue(res, rownum, i_most_common_freqs));
                              11319         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_histogram_bounds))
                              11320                 :            508 :             appendNamedArgument(out, fout, "histogram_bounds", "text",
                              11321                 :            508 :                                 PQgetvalue(res, rownum, i_histogram_bounds));
                              11322         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_correlation))
                              11323                 :            787 :             appendNamedArgument(out, fout, "correlation", "real",
                              11324                 :            787 :                                 PQgetvalue(res, rownum, i_correlation));
                              11325         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_most_common_elems))
                              11326                 :              8 :             appendNamedArgument(out, fout, "most_common_elems", "text",
                              11327                 :              8 :                                 PQgetvalue(res, rownum, i_most_common_elems));
                              11328         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_most_common_elem_freqs))
                              11329                 :              8 :             appendNamedArgument(out, fout, "most_common_elem_freqs", "real[]",
                              11330                 :              8 :                                 PQgetvalue(res, rownum, i_most_common_elem_freqs));
                              11331         [ +  + ]:            827 :         if (!PQgetisnull(res, rownum, i_elem_count_histogram))
                              11332                 :              7 :             appendNamedArgument(out, fout, "elem_count_histogram", "real[]",
                              11333                 :              7 :                                 PQgetvalue(res, rownum, i_elem_count_histogram));
                              11334         [ +  - ]:            827 :         if (fout->remoteVersion >= 170000)
                              11335                 :                :         {
                              11336         [ +  + ]:            827 :             if (!PQgetisnull(res, rownum, i_range_length_histogram))
                              11337                 :              4 :                 appendNamedArgument(out, fout, "range_length_histogram", "text",
                              11338                 :              4 :                                     PQgetvalue(res, rownum, i_range_length_histogram));
                              11339         [ +  + ]:            827 :             if (!PQgetisnull(res, rownum, i_range_empty_frac))
                              11340                 :              4 :                 appendNamedArgument(out, fout, "range_empty_frac", "real",
                              11341                 :              4 :                                     PQgetvalue(res, rownum, i_range_empty_frac));
                              11342         [ +  + ]:            827 :             if (!PQgetisnull(res, rownum, i_range_bounds_histogram))
                              11343                 :              4 :                 appendNamedArgument(out, fout, "range_bounds_histogram", "text",
                              11344                 :              4 :                                     PQgetvalue(res, rownum, i_range_bounds_histogram));
                              11345                 :                :         }
                              11346                 :            827 :         appendPQExpBufferStr(out, "\n);\n");
                              11347                 :                :     }
                              11348                 :                : 
  206 nathan@postgresql.or    11349                 :           3226 :     destroyPQExpBuffer(query);
                              11350                 :           3226 :     return out->data;
                              11351                 :                : }
                              11352                 :                : 
                              11353                 :                : /*
                              11354                 :                :  * dumpRelationStats --
                              11355                 :                :  *
                              11356                 :                :  * Make an ArchiveEntry for the relation statistics.  The Archiver will take
                              11357                 :                :  * care of gathering the statistics and generating the restore commands when
                              11358                 :                :  * they are needed.
                              11359                 :                :  */
                              11360                 :                : static void
                              11361                 :           3295 : dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
                              11362                 :                : {
                              11363                 :           3295 :     const DumpableObject *dobj = &rsinfo->dobj;
                              11364                 :                : 
                              11365                 :                :     /* nothing to do if we are not dumping statistics */
                              11366         [ -  + ]:           3295 :     if (!fout->dopt->dumpStatistics)
  206 nathan@postgresql.or    11367                 :UBC           0 :         return;
                              11368                 :                : 
  249 jdavis@postgresql.or    11369                 :CBC        3295 :     ArchiveEntry(fout, nilCatalogId, createDumpId(),
  242                         11370                 :           3295 :                  ARCHIVE_OPTS(.tag = dobj->name,
                              11371                 :                :                               .namespace = dobj->namespace->dobj.name,
                              11372                 :                :                               .description = "STATISTICS DATA",
                              11373                 :                :                               .section = rsinfo->section,
                              11374                 :                :                               .defnFn = dumpRelationStats_dumper,
                              11375                 :                :                               .defnArg = rsinfo,
                              11376                 :                :                               .deps = dobj->dependencies,
                              11377                 :                :                               .nDeps = dobj->nDeps));
                              11378                 :                : }
                              11379                 :                : 
                              11380                 :                : /*
                              11381                 :                :  * dumpTableComment --
                              11382                 :                :  *
                              11383                 :                :  * As above, but dump comments for both the specified table (or view)
                              11384                 :                :  * and its columns.
                              11385                 :                :  */
                              11386                 :                : static void
 1720 peter@eisentraut.org    11387                 :             74 : dumpTableComment(Archive *fout, const TableInfo *tbinfo,
                              11388                 :                :                  const char *reltypename)
                              11389                 :                : {
 3575 tgl@sss.pgh.pa.us       11390                 :             74 :     DumpOptions *dopt = fout->dopt;
                              11391                 :                :     CommentItem *comments;
                              11392                 :                :     int         ncomments;
                              11393                 :                :     PQExpBuffer query;
                              11394                 :                :     PQExpBuffer tag;
                              11395                 :                : 
                              11396                 :                :     /* do nothing, if --no-comments is supplied */
 2832                         11397         [ -  + ]:             74 :     if (dopt->no_comments)
 2832 tgl@sss.pgh.pa.us       11398                 :UBC           0 :         return;
                              11399                 :                : 
                              11400                 :                :     /* Comments are SCHEMA not data */
  336 nathan@postgresql.or    11401         [ -  + ]:CBC          74 :     if (!dopt->dumpSchema)
 8571 tgl@sss.pgh.pa.us       11402                 :UBC           0 :         return;
                              11403                 :                : 
                              11404                 :                :     /* Search for comments associated with relation, using table */
 1397 tgl@sss.pgh.pa.us       11405                 :CBC          74 :     ncomments = findComments(tbinfo->dobj.catId.tableoid,
 7891                         11406                 :             74 :                              tbinfo->dobj.catId.oid,
                              11407                 :                :                              &comments);
                              11408                 :                : 
                              11409                 :                :     /* If comments exist, build COMMENT ON statements */
                              11410         [ -  + ]:             74 :     if (ncomments <= 0)
 7891 tgl@sss.pgh.pa.us       11411                 :UBC           0 :         return;
                              11412                 :                : 
 8571 tgl@sss.pgh.pa.us       11413                 :CBC          74 :     query = createPQExpBuffer();
 2800                         11414                 :             74 :     tag = createPQExpBuffer();
                              11415                 :                : 
 7891                         11416         [ +  + ]:            212 :     while (ncomments > 0)
                              11417                 :                :     {
                              11418                 :            138 :         const char *descr = comments->descr;
                              11419                 :            138 :         int         objsubid = comments->objsubid;
                              11420                 :                : 
 8571                         11421         [ +  + ]:            138 :         if (objsubid == 0)
                              11422                 :                :         {
 2800                         11423                 :             32 :             resetPQExpBuffer(tag);
                              11424                 :             32 :             appendPQExpBuffer(tag, "%s %s", reltypename,
 7908                         11425                 :             32 :                               fmtId(tbinfo->dobj.name));
                              11426                 :                : 
 8571                         11427                 :             32 :             resetPQExpBuffer(query);
 2800                         11428                 :             32 :             appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
                              11429                 :             32 :                               fmtQualifiedDumpable(tbinfo));
 7092                         11430                 :             32 :             appendStringLiteralAH(query, descr, fout);
 4361 heikki.linnakangas@i    11431                 :             32 :             appendPQExpBufferStr(query, ";\n");
                              11432                 :                : 
 7996 tgl@sss.pgh.pa.us       11433                 :             32 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    11434                 :             32 :                          ARCHIVE_OPTS(.tag = tag->data,
                              11435                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              11436                 :                :                                       .owner = tbinfo->rolname,
                              11437                 :                :                                       .description = "COMMENT",
                              11438                 :                :                                       .section = SECTION_NONE,
                              11439                 :                :                                       .createStmt = query->data,
                              11440                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              11441                 :                :                                       .nDeps = 1));
                              11442                 :                :         }
 8571 tgl@sss.pgh.pa.us       11443   [ +  -  +  - ]:            106 :         else if (objsubid > 0 && objsubid <= tbinfo->numatts)
                              11444                 :                :         {
 2800                         11445                 :            106 :             resetPQExpBuffer(tag);
                              11446                 :            106 :             appendPQExpBuffer(tag, "COLUMN %s.",
 7908                         11447                 :            106 :                               fmtId(tbinfo->dobj.name));
 2800                         11448                 :            106 :             appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
                              11449                 :                : 
 8571                         11450                 :            106 :             resetPQExpBuffer(query);
 2800                         11451                 :            106 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              11452                 :            106 :                               fmtQualifiedDumpable(tbinfo));
                              11453                 :            106 :             appendPQExpBuffer(query, "%s IS ",
                              11454                 :            106 :                               fmtId(tbinfo->attnames[objsubid - 1]));
 7092                         11455                 :            106 :             appendStringLiteralAH(query, descr, fout);
 4361 heikki.linnakangas@i    11456                 :            106 :             appendPQExpBufferStr(query, ";\n");
                              11457                 :                : 
 7996 tgl@sss.pgh.pa.us       11458                 :            106 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    11459                 :            106 :                          ARCHIVE_OPTS(.tag = tag->data,
                              11460                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              11461                 :                :                                       .owner = tbinfo->rolname,
                              11462                 :                :                                       .description = "COMMENT",
                              11463                 :                :                                       .section = SECTION_NONE,
                              11464                 :                :                                       .createStmt = query->data,
                              11465                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              11466                 :                :                                       .nDeps = 1));
                              11467                 :                :         }
                              11468                 :                : 
 7891 tgl@sss.pgh.pa.us       11469                 :            138 :         comments++;
                              11470                 :            138 :         ncomments--;
                              11471                 :                :     }
                              11472                 :                : 
 8851                         11473                 :             74 :     destroyPQExpBuffer(query);
 2800                         11474                 :             74 :     destroyPQExpBuffer(tag);
                              11475                 :                : }
                              11476                 :                : 
                              11477                 :                : /*
                              11478                 :                :  * findComments --
                              11479                 :                :  *
                              11480                 :                :  * Find the comment(s), if any, associated with the given object.  All the
                              11481                 :                :  * objsubid values associated with the given classoid/objoid are found with
                              11482                 :                :  * one search.
                              11483                 :                :  */
                              11484                 :                : static int
 1397                         11485                 :           6713 : findComments(Oid classoid, Oid objoid, CommentItem **items)
                              11486                 :                : {
 7891                         11487                 :           6713 :     CommentItem *middle = NULL;
                              11488                 :                :     CommentItem *low;
                              11489                 :                :     CommentItem *high;
                              11490                 :                :     int         nmatch;
                              11491                 :                : 
                              11492                 :                :     /*
                              11493                 :                :      * Do binary search to find some item matching the object.
                              11494                 :                :      */
                              11495                 :           6713 :     low = &comments[0];
 7729 bruce@momjian.us        11496                 :           6713 :     high = &comments[ncomments - 1];
 7891 tgl@sss.pgh.pa.us       11497         [ +  + ]:          67147 :     while (low <= high)
                              11498                 :                :     {
                              11499                 :          67101 :         middle = low + (high - low) / 2;
                              11500                 :                : 
                              11501         [ +  + ]:          67101 :         if (classoid < middle->classoid)
                              11502                 :           7533 :             high = middle - 1;
                              11503         [ +  + ]:          59568 :         else if (classoid > middle->classoid)
                              11504                 :           7177 :             low = middle + 1;
                              11505         [ +  + ]:          52391 :         else if (objoid < middle->objoid)
                              11506                 :          22497 :             high = middle - 1;
                              11507         [ +  + ]:          29894 :         else if (objoid > middle->objoid)
                              11508                 :          23227 :             low = middle + 1;
                              11509                 :                :         else
                              11510                 :           6667 :             break;              /* found a match */
                              11511                 :                :     }
                              11512                 :                : 
                              11513         [ +  + ]:           6713 :     if (low > high)              /* no matches */
                              11514                 :                :     {
                              11515                 :             46 :         *items = NULL;
                              11516                 :             46 :         return 0;
                              11517                 :                :     }
                              11518                 :                : 
                              11519                 :                :     /*
                              11520                 :                :      * Now determine how many items match the object.  The search loop
                              11521                 :                :      * invariant still holds: only items between low and high inclusive could
                              11522                 :                :      * match.
                              11523                 :                :      */
                              11524                 :           6667 :     nmatch = 1;
                              11525         [ +  + ]:           6679 :     while (middle > low)
                              11526                 :                :     {
                              11527         [ +  + ]:           3231 :         if (classoid != middle[-1].classoid ||
                              11528         [ +  + ]:           3127 :             objoid != middle[-1].objoid)
                              11529                 :                :             break;
 7891 tgl@sss.pgh.pa.us       11530                 :GBC          12 :         middle--;
                              11531                 :             12 :         nmatch++;
                              11532                 :                :     }
                              11533                 :                : 
 7891 tgl@sss.pgh.pa.us       11534                 :CBC        6667 :     *items = middle;
                              11535                 :                : 
                              11536                 :           6667 :     middle += nmatch;
                              11537         [ +  + ]:           6719 :     while (middle <= high)
                              11538                 :                :     {
                              11539         [ +  + ]:           3486 :         if (classoid != middle->classoid ||
                              11540         [ +  + ]:           3176 :             objoid != middle->objoid)
                              11541                 :                :             break;
                              11542                 :             52 :         middle++;
                              11543                 :             52 :         nmatch++;
                              11544                 :                :     }
                              11545                 :                : 
                              11546                 :           6667 :     return nmatch;
                              11547                 :                : }
                              11548                 :                : 
                              11549                 :                : /*
                              11550                 :                :  * collectComments --
                              11551                 :                :  *
                              11552                 :                :  * Construct a table of all comments available for database objects;
                              11553                 :                :  * also set the has-comment component flag for each relevant object.
                              11554                 :                :  *
                              11555                 :                :  * We used to do per-object queries for the comments, but it's much faster
                              11556                 :                :  * to pull them all over at once, and on most databases the memory cost
                              11557                 :                :  * isn't high.
                              11558                 :                :  *
                              11559                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              11560                 :                :  */
                              11561                 :                : static void
 1421                         11562                 :            189 : collectComments(Archive *fout)
                              11563                 :                : {
                              11564                 :                :     PGresult   *res;
                              11565                 :                :     PQExpBuffer query;
                              11566                 :                :     int         i_description;
                              11567                 :                :     int         i_classoid;
                              11568                 :                :     int         i_objoid;
                              11569                 :                :     int         i_objsubid;
                              11570                 :                :     int         ntups;
                              11571                 :                :     int         i;
                              11572                 :                :     DumpableObject *dobj;
                              11573                 :                : 
 7891                         11574                 :            189 :     query = createPQExpBuffer();
                              11575                 :                : 
 3302                         11576                 :            189 :     appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
                              11577                 :                :                          "FROM pg_catalog.pg_description "
                              11578                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              11579                 :                : 
 5011 rhaas@postgresql.org    11580                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11581                 :                : 
                              11582                 :                :     /* Construct lookup table containing OIDs in numeric form */
                              11583                 :                : 
 7891 tgl@sss.pgh.pa.us       11584                 :            189 :     i_description = PQfnumber(res, "description");
                              11585                 :            189 :     i_classoid = PQfnumber(res, "classoid");
                              11586                 :            189 :     i_objoid = PQfnumber(res, "objoid");
                              11587                 :            189 :     i_objsubid = PQfnumber(res, "objsubid");
                              11588                 :                : 
                              11589                 :            189 :     ntups = PQntuples(res);
                              11590                 :                : 
 5085 bruce@momjian.us        11591                 :            189 :     comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
 1421 tgl@sss.pgh.pa.us       11592                 :            189 :     ncomments = 0;
                              11593                 :            189 :     dobj = NULL;
                              11594                 :                : 
 7891                         11595         [ +  + ]:        1016155 :     for (i = 0; i < ntups; i++)
                              11596                 :                :     {
                              11597                 :                :         CatalogId   objId;
                              11598                 :                :         int         subid;
                              11599                 :                : 
 1421                         11600                 :        1015966 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              11601                 :        1015966 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              11602                 :        1015966 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              11603                 :                : 
                              11604                 :                :         /* We needn't remember comments that don't match any dumpable object */
                              11605         [ +  + ]:        1015966 :         if (dobj == NULL ||
                              11606         [ +  + ]:         370631 :             dobj->catId.tableoid != objId.tableoid ||
                              11607         [ +  + ]:         368315 :             dobj->catId.oid != objId.oid)
                              11608                 :        1015876 :             dobj = findObjectByCatalogId(objId);
                              11609         [ +  + ]:        1015966 :         if (dobj == NULL)
                              11610                 :         645152 :             continue;
                              11611                 :                : 
                              11612                 :                :         /*
                              11613                 :                :          * Comments on columns of composite types are linked to the type's
                              11614                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
                              11615                 :                :          * in the type's own DumpableObject.
                              11616                 :                :          */
                              11617   [ +  +  +  - ]:         370814 :         if (subid != 0 && dobj->objType == DO_TABLE &&
                              11618         [ +  + ]:            194 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              11619                 :             45 :         {
                              11620                 :                :             TypeInfo   *cTypeInfo;
                              11621                 :                : 
                              11622                 :             45 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              11623         [ +  - ]:             45 :             if (cTypeInfo)
                              11624                 :             45 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                              11625                 :                :         }
                              11626                 :                :         else
                              11627                 :         370769 :             dobj->components |= DUMP_COMPONENT_COMMENT;
                              11628                 :                : 
                              11629                 :         370814 :         comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
                              11630                 :         370814 :         comments[ncomments].classoid = objId.tableoid;
                              11631                 :         370814 :         comments[ncomments].objoid = objId.oid;
                              11632                 :         370814 :         comments[ncomments].objsubid = subid;
                              11633                 :         370814 :         ncomments++;
                              11634                 :                :     }
                              11635                 :                : 
                              11636                 :            189 :     PQclear(res);
 7891                         11637                 :            189 :     destroyPQExpBuffer(query);
                              11638                 :            189 : }
                              11639                 :                : 
                              11640                 :                : /*
                              11641                 :                :  * dumpDumpableObject
                              11642                 :                :  *
                              11643                 :                :  * This routine and its subsidiaries are responsible for creating
                              11644                 :                :  * ArchiveEntries (TOC objects) for each object to be dumped.
                              11645                 :                :  */
                              11646                 :                : static void
 1421                         11647                 :         832618 : dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                              11648                 :                : {
                              11649                 :                :     /*
                              11650                 :                :      * Clear any dump-request bits for components that don't exist for this
                              11651                 :                :      * object.  (This makes it safe to initially use DUMP_COMPONENT_ALL as the
                              11652                 :                :      * request for every kind of object.)
                              11653                 :                :      */
                              11654                 :         832618 :     dobj->dump &= dobj->components;
                              11655                 :                : 
                              11656                 :                :     /* Now, short-circuit if there's nothing to be done here. */
                              11657         [ +  + ]:         832618 :     if (dobj->dump == 0)
                              11658                 :         753963 :         return;
                              11659                 :                : 
 7996                         11660   [ +  +  +  +  :          78655 :     switch (dobj->objType)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                        +  +  +  - ]
                              11661                 :                :     {
                              11662                 :            491 :         case DO_NAMESPACE:
 1720 peter@eisentraut.org    11663                 :            491 :             dumpNamespace(fout, (const NamespaceInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11664                 :            491 :             break;
 5375                         11665                 :             24 :         case DO_EXTENSION:
 1720 peter@eisentraut.org    11666                 :             24 :             dumpExtension(fout, (const ExtensionInfo *) dobj);
 5375 tgl@sss.pgh.pa.us       11667                 :             24 :             break;
 7996                         11668                 :            920 :         case DO_TYPE:
 1720 peter@eisentraut.org    11669                 :            920 :             dumpType(fout, (const TypeInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11670                 :            920 :             break;
 7179                         11671                 :             73 :         case DO_SHELL_TYPE:
 1720 peter@eisentraut.org    11672                 :             73 :             dumpShellType(fout, (const ShellTypeInfo *) dobj);
 7179 tgl@sss.pgh.pa.us       11673                 :             73 :             break;
 7996                         11674                 :           1818 :         case DO_FUNC:
 1720 peter@eisentraut.org    11675                 :           1818 :             dumpFunc(fout, (const FuncInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11676                 :           1818 :             break;
                              11677                 :            292 :         case DO_AGG:
 1720 peter@eisentraut.org    11678                 :            292 :             dumpAgg(fout, (const AggInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11679                 :            292 :             break;
                              11680                 :           2504 :         case DO_OPERATOR:
 1720 peter@eisentraut.org    11681                 :           2504 :             dumpOpr(fout, (const OprInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11682                 :           2504 :             break;
 3505 alvherre@alvh.no-ip.    11683                 :             80 :         case DO_ACCESS_METHOD:
 1720 peter@eisentraut.org    11684                 :             80 :             dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
 3505 alvherre@alvh.no-ip.    11685                 :             80 :             break;
 7996 tgl@sss.pgh.pa.us       11686                 :            660 :         case DO_OPCLASS:
 1720 peter@eisentraut.org    11687                 :            660 :             dumpOpclass(fout, (const OpclassInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11688                 :            660 :             break;
 6852                         11689                 :            549 :         case DO_OPFAMILY:
 1720 peter@eisentraut.org    11690                 :            549 :             dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
 6852 tgl@sss.pgh.pa.us       11691                 :            549 :             break;
 5371 peter_e@gmx.net         11692                 :           4643 :         case DO_COLLATION:
 1720 peter@eisentraut.org    11693                 :           4643 :             dumpCollation(fout, (const CollInfo *) dobj);
 5371 peter_e@gmx.net         11694                 :           4643 :             break;
 7996 tgl@sss.pgh.pa.us       11695                 :            422 :         case DO_CONVERSION:
 1720 peter@eisentraut.org    11696                 :            422 :             dumpConversion(fout, (const ConvInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11697                 :            422 :             break;
                              11698                 :          31464 :         case DO_TABLE:
 1720 peter@eisentraut.org    11699                 :          31464 :             dumpTable(fout, (const TableInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11700                 :          31464 :             break;
 1750                         11701                 :           1381 :         case DO_TABLE_ATTACH:
 1720 peter@eisentraut.org    11702                 :           1381 :             dumpTableAttach(fout, (const TableAttachInfo *) dobj);
 1750 tgl@sss.pgh.pa.us       11703                 :           1381 :             break;
 7996                         11704                 :           1032 :         case DO_ATTRDEF:
 1720 peter@eisentraut.org    11705                 :           1032 :             dumpAttrDef(fout, (const AttrDefInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11706                 :           1032 :             break;
                              11707                 :           2574 :         case DO_INDEX:
 1720 peter@eisentraut.org    11708                 :           2574 :             dumpIndex(fout, (const IndxInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11709                 :           2574 :             break;
 2838 alvherre@alvh.no-ip.    11710                 :            564 :         case DO_INDEX_ATTACH:
 1720 peter@eisentraut.org    11711                 :            564 :             dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
 2838 alvherre@alvh.no-ip.    11712                 :            564 :             break;
 3139                         11713                 :            133 :         case DO_STATSEXT:
 1720 peter@eisentraut.org    11714                 :            133 :             dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
 3139 alvherre@alvh.no-ip.    11715                 :            133 :             break;
 4621 kgrittn@postgresql.o    11716                 :            348 :         case DO_REFRESH_MATVIEW:
 1720 peter@eisentraut.org    11717                 :            348 :             refreshMatViewData(fout, (const TableDataInfo *) dobj);
 4621 kgrittn@postgresql.o    11718                 :            348 :             break;
 7996 tgl@sss.pgh.pa.us       11719                 :           1132 :         case DO_RULE:
 1720 peter@eisentraut.org    11720                 :           1132 :             dumpRule(fout, (const RuleInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11721                 :           1132 :             break;
                              11722                 :            523 :         case DO_TRIGGER:
 1720 peter@eisentraut.org    11723                 :            523 :             dumpTrigger(fout, (const TriggerInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11724                 :            523 :             break;
 4849 rhaas@postgresql.org    11725                 :             42 :         case DO_EVENT_TRIGGER:
 1720 peter@eisentraut.org    11726                 :             42 :             dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
 4849 rhaas@postgresql.org    11727                 :             42 :             break;
 7996 tgl@sss.pgh.pa.us       11728                 :           2302 :         case DO_CONSTRAINT:
 1720 peter@eisentraut.org    11729                 :           2302 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11730                 :           2302 :             break;
                              11731                 :            171 :         case DO_FK_CONSTRAINT:
 1720 peter@eisentraut.org    11732                 :            171 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11733                 :            171 :             break;
                              11734                 :             82 :         case DO_PROCLANG:
 1720 peter@eisentraut.org    11735                 :             82 :             dumpProcLang(fout, (const ProcLangInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11736                 :             82 :             break;
                              11737                 :             67 :         case DO_CAST:
 1720 peter@eisentraut.org    11738                 :             67 :             dumpCast(fout, (const CastInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11739                 :             67 :             break;
 3837 peter_e@gmx.net         11740                 :             42 :         case DO_TRANSFORM:
 1720 peter@eisentraut.org    11741                 :             42 :             dumpTransform(fout, (const TransformInfo *) dobj);
 3837 peter_e@gmx.net         11742                 :             42 :             break;
 3352                         11743                 :            393 :         case DO_SEQUENCE_SET:
 1720 peter@eisentraut.org    11744                 :            393 :             dumpSequenceData(fout, (const TableDataInfo *) dobj);
 3352 peter_e@gmx.net         11745                 :            393 :             break;
 7996 tgl@sss.pgh.pa.us       11746                 :           4224 :         case DO_TABLE_DATA:
 1720 peter@eisentraut.org    11747                 :           4224 :             dumpTableData(fout, (const TableDataInfo *) dobj);
 7996 tgl@sss.pgh.pa.us       11748                 :           4224 :             break;
 6126                         11749                 :          14063 :         case DO_DUMMY_TYPE:
                              11750                 :                :             /* table rowtypes and array types are never dumped separately */
 7908                         11751                 :          14063 :             break;
 6642                         11752                 :             41 :         case DO_TSPARSER:
 1720 peter@eisentraut.org    11753                 :             41 :             dumpTSParser(fout, (const TSParserInfo *) dobj);
 6642 tgl@sss.pgh.pa.us       11754                 :             41 :             break;
                              11755                 :            173 :         case DO_TSDICT:
 1720 peter@eisentraut.org    11756                 :            173 :             dumpTSDictionary(fout, (const TSDictInfo *) dobj);
 6642 tgl@sss.pgh.pa.us       11757                 :            173 :             break;
                              11758                 :             53 :         case DO_TSTEMPLATE:
 1720 peter@eisentraut.org    11759                 :             53 :             dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
 6642 tgl@sss.pgh.pa.us       11760                 :             53 :             break;
                              11761                 :            148 :         case DO_TSCONFIG:
 1720 peter@eisentraut.org    11762                 :            148 :             dumpTSConfig(fout, (const TSConfigInfo *) dobj);
 6642 tgl@sss.pgh.pa.us       11763                 :            148 :             break;
 6156 peter_e@gmx.net         11764                 :             52 :         case DO_FDW:
 1720 peter@eisentraut.org    11765                 :             52 :             dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
 6156 peter_e@gmx.net         11766                 :             52 :             break;
                              11767                 :             56 :         case DO_FOREIGN_SERVER:
 1720 peter@eisentraut.org    11768                 :             56 :             dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
 6156 peter_e@gmx.net         11769                 :             56 :             break;
 5866 tgl@sss.pgh.pa.us       11770                 :            160 :         case DO_DEFAULT_ACL:
 1720 peter@eisentraut.org    11771                 :            160 :             dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
 5866 tgl@sss.pgh.pa.us       11772                 :            160 :             break;
 1057 peter@eisentraut.org    11773                 :             87 :         case DO_LARGE_OBJECT:
                              11774                 :             87 :             dumpLO(fout, (const LoInfo *) dobj);
 5730 tgl@sss.pgh.pa.us       11775                 :             87 :             break;
 1057 peter@eisentraut.org    11776                 :             93 :         case DO_LARGE_OBJECT_DATA:
 3491 sfrost@snowman.net      11777         [ +  - ]:             93 :             if (dobj->dump & DUMP_COMPONENT_DATA)
                              11778                 :                :             {
                              11779                 :                :                 LoInfo     *loinfo;
                              11780                 :                :                 TocEntry   *te;
                              11781                 :                : 
  574 tgl@sss.pgh.pa.us       11782                 :             93 :                 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
                              11783         [ -  + ]:             93 :                 if (loinfo == NULL)
  574 tgl@sss.pgh.pa.us       11784                 :UBC           0 :                     pg_fatal("missing metadata for large objects \"%s\"",
                              11785                 :                :                              dobj->name);
                              11786                 :                : 
 2600 tgl@sss.pgh.pa.us       11787                 :CBC          93 :                 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
 2460 alvherre@alvh.no-ip.    11788                 :             93 :                                   ARCHIVE_OPTS(.tag = dobj->name,
                              11789                 :                :                                                .owner = loinfo->rolname,
                              11790                 :                :                                                .description = "BLOBS",
                              11791                 :                :                                                .section = SECTION_DATA,
                              11792                 :                :                                                .deps = dobj->dependencies,
                              11793                 :                :                                                .nDeps = dobj->nDeps,
                              11794                 :                :                                                .dumpFn = dumpLOs,
                              11795                 :                :                                                .dumpArg = loinfo));
                              11796                 :                : 
                              11797                 :                :                 /*
                              11798                 :                :                  * Set the TocEntry's dataLength in case we are doing a
                              11799                 :                :                  * parallel dump and want to order dump jobs by table size.
                              11800                 :                :                  * (We need some size estimate for every TocEntry with a
                              11801                 :                :                  * DataDumper function.)  We don't currently have any cheap
                              11802                 :                :                  * way to estimate the size of LOs, but fortunately it doesn't
                              11803                 :                :                  * matter too much as long as we get large batches of LOs
                              11804                 :                :                  * processed reasonably early.  Assume 8K per blob.
                              11805                 :                :                  */
  574 tgl@sss.pgh.pa.us       11806                 :             93 :                 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
                              11807                 :                :             }
 7908                         11808                 :             93 :             break;
 3987 sfrost@snowman.net      11809                 :            326 :         case DO_POLICY:
 1720 peter@eisentraut.org    11810                 :            326 :             dumpPolicy(fout, (const PolicyInfo *) dobj);
 4056 sfrost@snowman.net      11811                 :            326 :             break;
 3203 peter_e@gmx.net         11812                 :            285 :         case DO_PUBLICATION:
 1720 peter@eisentraut.org    11813                 :            285 :             dumpPublication(fout, (const PublicationInfo *) dobj);
 3203 peter_e@gmx.net         11814                 :            285 :             break;
                              11815                 :            284 :         case DO_PUBLICATION_REL:
 1720 peter@eisentraut.org    11816                 :            284 :             dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
 3203 peter_e@gmx.net         11817                 :            284 :             break;
 1448 akapila@postgresql.o    11818                 :             99 :         case DO_PUBLICATION_TABLE_IN_SCHEMA:
 1461                         11819                 :             99 :             dumpPublicationNamespace(fout,
                              11820                 :                :                                      (const PublicationSchemaInfo *) dobj);
                              11821                 :             99 :             break;
 3203 peter_e@gmx.net         11822                 :            110 :         case DO_SUBSCRIPTION:
 1720 peter@eisentraut.org    11823                 :            110 :             dumpSubscription(fout, (const SubscriptionInfo *) dobj);
 3203 peter_e@gmx.net         11824                 :            110 :             break;
  664 akapila@postgresql.o    11825                 :              2 :         case DO_SUBSCRIPTION_REL:
                              11826                 :              2 :             dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
                              11827                 :              2 :             break;
  249 jdavis@postgresql.or    11828                 :           3295 :         case DO_REL_STATS:
                              11829                 :           3295 :             dumpRelationStats(fout, (const RelStatsInfo *) dobj);
                              11830                 :           3295 :             break;
 4872 tgl@sss.pgh.pa.us       11831                 :            378 :         case DO_PRE_DATA_BOUNDARY:
                              11832                 :                :         case DO_POST_DATA_BOUNDARY:
                              11833                 :                :             /* never dumped, nothing to do */
                              11834                 :            378 :             break;
                              11835                 :                :     }
                              11836                 :                : }
                              11837                 :                : 
                              11838                 :                : /*
                              11839                 :                :  * dumpNamespace
                              11840                 :                :  *    writes out to fout the queries to recreate a user-defined namespace
                              11841                 :                :  */
                              11842                 :                : static void
 1720 peter@eisentraut.org    11843                 :            491 : dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
                              11844                 :                : {
 3575 tgl@sss.pgh.pa.us       11845                 :            491 :     DumpOptions *dopt = fout->dopt;
                              11846                 :                :     PQExpBuffer q;
                              11847                 :                :     PQExpBuffer delq;
                              11848                 :                :     char       *qnspname;
                              11849                 :                : 
                              11850                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    11851         [ +  + ]:            491 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       11852                 :             28 :         return;
                              11853                 :                : 
                              11854                 :            463 :     q = createPQExpBuffer();
                              11855                 :            463 :     delq = createPQExpBuffer();
                              11856                 :                : 
 5085 bruce@momjian.us        11857                 :            463 :     qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
                              11858                 :                : 
 1582 noah@leadboat.com       11859         [ +  + ]:            463 :     if (nspinfo->create)
                              11860                 :                :     {
                              11861                 :            309 :         appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
                              11862                 :            309 :         appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
                              11863                 :                :     }
                              11864                 :                :     else
                              11865                 :                :     {
                              11866                 :                :         /* see selectDumpableNamespace() */
                              11867                 :            154 :         appendPQExpBufferStr(delq,
                              11868                 :                :                              "-- *not* dropping schema, since initdb creates it\n");
                              11869                 :            154 :         appendPQExpBufferStr(q,
                              11870                 :                :                              "-- *not* creating schema, since initdb creates it\n");
                              11871                 :                :     }
                              11872                 :                : 
 4031 alvherre@alvh.no-ip.    11873         [ +  + ]:            463 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       11874                 :             90 :         binary_upgrade_extension_member(q, &nspinfo->dobj,
                              11875                 :                :                                         "SCHEMA", qnspname, NULL);
                              11876                 :                : 
 3491 sfrost@snowman.net      11877         [ +  + ]:            463 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11878                 :            185 :         ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    11879                 :            185 :                      ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
                              11880                 :                :                                   .owner = nspinfo->rolname,
                              11881                 :                :                                   .description = "SCHEMA",
                              11882                 :                :                                   .section = SECTION_PRE_DATA,
                              11883                 :                :                                   .createStmt = q->data,
                              11884                 :                :                                   .dropStmt = delq->data));
                              11885                 :                : 
                              11886                 :                :     /* Dump Schema Comments and Security Labels */
 3491 sfrost@snowman.net      11887         [ +  + ]:            463 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              11888                 :                :     {
 1582 noah@leadboat.com       11889                 :            159 :         const char *initdb_comment = NULL;
                              11890                 :                : 
                              11891   [ +  +  +  + ]:            159 :         if (!nspinfo->create && strcmp(qnspname, "public") == 0)
 1413 tgl@sss.pgh.pa.us       11892                 :            120 :             initdb_comment = "standard public schema";
 1582 noah@leadboat.com       11893                 :            159 :         dumpCommentExtended(fout, "SCHEMA", qnspname,
                              11894                 :            159 :                             NULL, nspinfo->rolname,
                              11895                 :            159 :                             nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
                              11896                 :                :                             initdb_comment);
                              11897                 :                :     }
                              11898                 :                : 
 3491 sfrost@snowman.net      11899         [ -  + ]:            463 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       11900                 :UBC           0 :         dumpSecLabel(fout, "SCHEMA", qnspname,
 3491 sfrost@snowman.net      11901                 :              0 :                      NULL, nspinfo->rolname,
                              11902                 :              0 :                      nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
                              11903                 :                : 
 3491 sfrost@snowman.net      11904         [ +  + ]:CBC         463 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       11905                 :            361 :         dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
                              11906                 :                :                 qnspname, NULL, NULL,
  574                         11907                 :            361 :                 NULL, nspinfo->rolname, &nspinfo->dacl);
                              11908                 :                : 
 7996                         11909                 :            463 :     free(qnspname);
                              11910                 :                : 
 8571                         11911                 :            463 :     destroyPQExpBuffer(q);
                              11912                 :            463 :     destroyPQExpBuffer(delq);
                              11913                 :                : }
                              11914                 :                : 
                              11915                 :                : /*
                              11916                 :                :  * dumpExtension
                              11917                 :                :  *    writes out to fout the queries to recreate an extension
                              11918                 :                :  */
                              11919                 :                : static void
 1720 peter@eisentraut.org    11920                 :             24 : dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
                              11921                 :                : {
 3575 tgl@sss.pgh.pa.us       11922                 :             24 :     DumpOptions *dopt = fout->dopt;
                              11923                 :                :     PQExpBuffer q;
                              11924                 :                :     PQExpBuffer delq;
                              11925                 :                :     char       *qextname;
                              11926                 :                : 
                              11927                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    11928         [ +  + ]:             24 :     if (!dopt->dumpSchema)
 5375 tgl@sss.pgh.pa.us       11929                 :              1 :         return;
                              11930                 :                : 
                              11931                 :             23 :     q = createPQExpBuffer();
                              11932                 :             23 :     delq = createPQExpBuffer();
                              11933                 :                : 
 5085 bruce@momjian.us        11934                 :             23 :     qextname = pg_strdup(fmtId(extinfo->dobj.name));
                              11935                 :                : 
 5375 tgl@sss.pgh.pa.us       11936                 :             23 :     appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
                              11937                 :                : 
 4031 alvherre@alvh.no-ip.    11938         [ +  + ]:             23 :     if (!dopt->binary_upgrade)
                              11939                 :                :     {
                              11940                 :                :         /*
                              11941                 :                :          * In a regular dump, we simply create the extension, intentionally
                              11942                 :                :          * not specifying a version, so that the destination installation's
                              11943                 :                :          * default version is used.
                              11944                 :                :          *
                              11945                 :                :          * Use of IF NOT EXISTS here is unlike our behavior for other object
                              11946                 :                :          * types; but there are various scenarios in which it's convenient to
                              11947                 :                :          * manually create the desired extension before restoring, so we
                              11948                 :                :          * prefer to allow it to exist already.
                              11949                 :                :          */
 5351 tgl@sss.pgh.pa.us       11950                 :             17 :         appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
 5374                         11951                 :             17 :                           qextname, fmtId(extinfo->namespace));
                              11952                 :                :     }
                              11953                 :                :     else
                              11954                 :                :     {
                              11955                 :                :         /*
                              11956                 :                :          * In binary-upgrade mode, it's critical to reproduce the state of the
                              11957                 :                :          * database exactly, so our procedure is to create an empty extension,
                              11958                 :                :          * restore all the contained objects normally, and add them to the
                              11959                 :                :          * extension one by one.  This function performs just the first of
                              11960                 :                :          * those steps.  binary_upgrade_extension_member() takes care of
                              11961                 :                :          * adding member objects as they're created.
                              11962                 :                :          */
                              11963                 :                :         int         i;
                              11964                 :                :         int         n;
                              11965                 :                : 
 4361 heikki.linnakangas@i    11966                 :              6 :         appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
                              11967                 :                : 
                              11968                 :                :         /*
                              11969                 :                :          * We unconditionally create the extension, so we must drop it if it
                              11970                 :                :          * exists.  This could happen if the user deleted 'plpgsql' and then
                              11971                 :                :          * readded it, causing its oid to be greater than g_last_builtin_oid.
                              11972                 :                :          */
 4863 bruce@momjian.us        11973                 :              6 :         appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
                              11974                 :                : 
 4361 heikki.linnakangas@i    11975                 :              6 :         appendPQExpBufferStr(q,
                              11976                 :                :                              "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
 5374 tgl@sss.pgh.pa.us       11977                 :              6 :         appendStringLiteralAH(q, extinfo->dobj.name, fout);
 4361 heikki.linnakangas@i    11978                 :              6 :         appendPQExpBufferStr(q, ", ");
 5374 tgl@sss.pgh.pa.us       11979                 :              6 :         appendStringLiteralAH(q, extinfo->namespace, fout);
 4361 heikki.linnakangas@i    11980                 :              6 :         appendPQExpBufferStr(q, ", ");
 5374 tgl@sss.pgh.pa.us       11981         [ +  - ]:              6 :         appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
 5372                         11982                 :              6 :         appendStringLiteralAH(q, extinfo->extversion, fout);
 4361 heikki.linnakangas@i    11983                 :              6 :         appendPQExpBufferStr(q, ", ");
                              11984                 :                : 
                              11985                 :                :         /*
                              11986                 :                :          * Note that we're pushing extconfig (an OID array) back into
                              11987                 :                :          * pg_extension exactly as-is.  This is OK because pg_class OIDs are
                              11988                 :                :          * preserved in binary upgrade.
                              11989                 :                :          */
 5374 tgl@sss.pgh.pa.us       11990         [ +  + ]:              6 :         if (strlen(extinfo->extconfig) > 2)
                              11991                 :              1 :             appendStringLiteralAH(q, extinfo->extconfig, fout);
                              11992                 :                :         else
 4361 heikki.linnakangas@i    11993                 :GBC           5 :             appendPQExpBufferStr(q, "NULL");
 4361 heikki.linnakangas@i    11994                 :CBC           6 :         appendPQExpBufferStr(q, ", ");
 5374 tgl@sss.pgh.pa.us       11995         [ +  + ]:              6 :         if (strlen(extinfo->extcondition) > 2)
                              11996                 :              1 :             appendStringLiteralAH(q, extinfo->extcondition, fout);
                              11997                 :                :         else
 4361 heikki.linnakangas@i    11998                 :GBC           5 :             appendPQExpBufferStr(q, "NULL");
 4361 heikki.linnakangas@i    11999                 :CBC           6 :         appendPQExpBufferStr(q, ", ");
                              12000                 :              6 :         appendPQExpBufferStr(q, "ARRAY[");
 5374 tgl@sss.pgh.pa.us       12001                 :              6 :         n = 0;
                              12002         [ +  + ]:             12 :         for (i = 0; i < extinfo->dobj.nDeps; i++)
                              12003                 :                :         {
                              12004                 :                :             DumpableObject *extobj;
                              12005                 :                : 
                              12006                 :              6 :             extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
                              12007   [ +  -  -  + ]:              6 :             if (extobj && extobj->objType == DO_EXTENSION)
                              12008                 :                :             {
 5374 tgl@sss.pgh.pa.us       12009         [ #  # ]:UBC           0 :                 if (n++ > 0)
 4361 heikki.linnakangas@i    12010                 :              0 :                     appendPQExpBufferChar(q, ',');
 5374 tgl@sss.pgh.pa.us       12011                 :              0 :                 appendStringLiteralAH(q, extobj->name, fout);
                              12012                 :                :             }
                              12013                 :                :         }
 4361 heikki.linnakangas@i    12014                 :CBC           6 :         appendPQExpBufferStr(q, "]::pg_catalog.text[]");
                              12015                 :              6 :         appendPQExpBufferStr(q, ");\n");
                              12016                 :                :     }
                              12017                 :                : 
 3491 sfrost@snowman.net      12018         [ +  - ]:             23 :     if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12019                 :             23 :         ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12020                 :             23 :                      ARCHIVE_OPTS(.tag = extinfo->dobj.name,
                              12021                 :                :                                   .description = "EXTENSION",
                              12022                 :                :                                   .section = SECTION_PRE_DATA,
                              12023                 :                :                                   .createStmt = q->data,
                              12024                 :                :                                   .dropStmt = delq->data));
                              12025                 :                : 
                              12026                 :                :     /* Dump Extension Comments */
 3491 sfrost@snowman.net      12027         [ +  - ]:             23 :     if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12028                 :             23 :         dumpComment(fout, "EXTENSION", qextname,
                              12029                 :                :                     NULL, "",
 3491 sfrost@snowman.net      12030                 :             23 :                     extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
                              12031                 :                : 
 5375 tgl@sss.pgh.pa.us       12032                 :             23 :     free(qextname);
                              12033                 :                : 
                              12034                 :             23 :     destroyPQExpBuffer(q);
                              12035                 :             23 :     destroyPQExpBuffer(delq);
                              12036                 :                : }
                              12037                 :                : 
                              12038                 :                : /*
                              12039                 :                :  * dumpType
                              12040                 :                :  *    writes out to fout the queries to recreate a user-defined type
                              12041                 :                :  */
                              12042                 :                : static void
 1720 peter@eisentraut.org    12043                 :            920 : dumpType(Archive *fout, const TypeInfo *tyinfo)
                              12044                 :                : {
 3575 tgl@sss.pgh.pa.us       12045                 :            920 :     DumpOptions *dopt = fout->dopt;
                              12046                 :                : 
                              12047                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    12048         [ +  + ]:            920 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       12049                 :             49 :         return;
                              12050                 :                : 
                              12051                 :                :     /* Dump out in proper style */
 5787 bruce@momjian.us        12052         [ +  + ]:            871 :     if (tyinfo->typtype == TYPTYPE_BASE)
 3575 tgl@sss.pgh.pa.us       12053                 :            280 :         dumpBaseType(fout, tyinfo);
 5787 bruce@momjian.us        12054         [ +  + ]:            591 :     else if (tyinfo->typtype == TYPTYPE_DOMAIN)
 3575 tgl@sss.pgh.pa.us       12055                 :            152 :         dumpDomain(fout, tyinfo);
 5787 bruce@momjian.us        12056         [ +  + ]:            439 :     else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
 3575 tgl@sss.pgh.pa.us       12057                 :            130 :         dumpCompositeType(fout, tyinfo);
 5787 bruce@momjian.us        12058         [ +  + ]:            309 :     else if (tyinfo->typtype == TYPTYPE_ENUM)
 3575 tgl@sss.pgh.pa.us       12059                 :             85 :         dumpEnumType(fout, tyinfo);
 5107 heikki.linnakangas@i    12060         [ +  + ]:            224 :     else if (tyinfo->typtype == TYPTYPE_RANGE)
 3575 tgl@sss.pgh.pa.us       12061                 :            112 :         dumpRangeType(fout, tyinfo);
 3737                         12062   [ +  -  +  + ]:            112 :     else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
 3575                         12063                 :             37 :         dumpUndefinedType(fout, tyinfo);
                              12064                 :                :     else
 2401 peter@eisentraut.org    12065                 :             75 :         pg_log_warning("typtype of data type \"%s\" appears to be invalid",
                              12066                 :                :                        tyinfo->dobj.name);
                              12067                 :                : }
                              12068                 :                : 
                              12069                 :                : /*
                              12070                 :                :  * dumpEnumType
                              12071                 :                :  *    writes out to fout the queries to recreate a user-defined enum type
                              12072                 :                :  */
                              12073                 :                : static void
 1720                         12074                 :             85 : dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
                              12075                 :                : {
 3575 tgl@sss.pgh.pa.us       12076                 :             85 :     DumpOptions *dopt = fout->dopt;
 6783                         12077                 :             85 :     PQExpBuffer q = createPQExpBuffer();
                              12078                 :             85 :     PQExpBuffer delq = createPQExpBuffer();
                              12079                 :             85 :     PQExpBuffer query = createPQExpBuffer();
                              12080                 :                :     PGresult   *res;
                              12081                 :                :     int         num,
                              12082                 :                :                 i;
                              12083                 :                :     Oid         enum_oid;
                              12084                 :                :     char       *qtypname;
                              12085                 :                :     char       *qualtypname;
                              12086                 :                :     char       *label;
                              12087                 :                :     int         i_enumlabel;
                              12088                 :                :     int         i_oid;
                              12089                 :                : 
 1421                         12090         [ +  + ]:             85 :     if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
                              12091                 :                :     {
                              12092                 :                :         /* Set up query for enum-specific details */
                              12093                 :             40 :         appendPQExpBufferStr(query,
                              12094                 :                :                              "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
                              12095                 :                :                              "SELECT oid, enumlabel "
                              12096                 :                :                              "FROM pg_catalog.pg_enum "
                              12097                 :                :                              "WHERE enumtypid = $1 "
                              12098                 :                :                              "ORDER BY enumsortorder");
                              12099                 :                : 
                              12100                 :             40 :         ExecuteSqlStatement(fout, query->data);
                              12101                 :                : 
                              12102                 :             40 :         fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
                              12103                 :                :     }
                              12104                 :                : 
                              12105                 :             85 :     printfPQExpBuffer(query,
                              12106                 :                :                       "EXECUTE dumpEnumType('%u')",
                              12107                 :             85 :                       tyinfo->dobj.catId.oid);
                              12108                 :                : 
 5011 rhaas@postgresql.org    12109                 :             85 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              12110                 :                : 
 6783 tgl@sss.pgh.pa.us       12111                 :             85 :     num = PQntuples(res);
                              12112                 :                : 
 4705                         12113                 :             85 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12114                 :             85 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12115                 :                : 
                              12116                 :                :     /*
                              12117                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              12118                 :                :      * functions are generic and do not get dropped.
                              12119                 :                :      */
                              12120                 :             85 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12121                 :                : 
 4031 alvherre@alvh.no-ip.    12122         [ +  + ]:             85 :     if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    12123                 :              6 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2949 tgl@sss.pgh.pa.us       12124                 :              6 :                                                  tyinfo->dobj.catId.oid,
                              12125                 :                :                                                  false, false);
                              12126                 :                : 
 5783 bruce@momjian.us        12127                 :             85 :     appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
                              12128                 :                :                       qualtypname);
                              12129                 :                : 
 4031 alvherre@alvh.no-ip.    12130         [ +  + ]:             85 :     if (!dopt->binary_upgrade)
                              12131                 :                :     {
 1522 dgustafsson@postgres    12132                 :             79 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              12133                 :                : 
                              12134                 :                :         /* Labels with server-assigned oids */
 5783 bruce@momjian.us        12135         [ +  + ]:            482 :         for (i = 0; i < num; i++)
                              12136                 :                :         {
 1522 dgustafsson@postgres    12137                 :            403 :             label = PQgetvalue(res, i, i_enumlabel);
 5783 bruce@momjian.us        12138         [ +  + ]:            403 :             if (i > 0)
 4361 heikki.linnakangas@i    12139                 :            324 :                 appendPQExpBufferChar(q, ',');
                              12140                 :            403 :             appendPQExpBufferStr(q, "\n    ");
 5783 bruce@momjian.us        12141                 :            403 :             appendStringLiteralAH(q, label, fout);
                              12142                 :                :         }
                              12143                 :                :     }
                              12144                 :                : 
 4361 heikki.linnakangas@i    12145                 :             85 :     appendPQExpBufferStr(q, "\n);\n");
                              12146                 :                : 
 4031 alvherre@alvh.no-ip.    12147         [ +  + ]:             85 :     if (dopt->binary_upgrade)
                              12148                 :                :     {
 1522 dgustafsson@postgres    12149                 :              6 :         i_oid = PQfnumber(res, "oid");
                              12150                 :              6 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              12151                 :                : 
                              12152                 :                :         /* Labels with dump-assigned (preserved) oids */
 5783 bruce@momjian.us        12153         [ +  + ]:             62 :         for (i = 0; i < num; i++)
                              12154                 :                :         {
 1522 dgustafsson@postgres    12155                 :             56 :             enum_oid = atooid(PQgetvalue(res, i, i_oid));
                              12156                 :             56 :             label = PQgetvalue(res, i, i_enumlabel);
                              12157                 :                : 
 5783 bruce@momjian.us        12158         [ +  + ]:             56 :             if (i == 0)
 4361 heikki.linnakangas@i    12159                 :              6 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
 5783 bruce@momjian.us        12160                 :             56 :             appendPQExpBuffer(q,
                              12161                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                              12162                 :                :                               enum_oid);
 2800 tgl@sss.pgh.pa.us       12163                 :             56 :             appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
 5783 bruce@momjian.us        12164                 :             56 :             appendStringLiteralAH(q, label, fout);
 4361 heikki.linnakangas@i    12165                 :             56 :             appendPQExpBufferStr(q, ";\n\n");
                              12166                 :                :         }
                              12167                 :                :     }
                              12168                 :                : 
 4031 alvherre@alvh.no-ip.    12169         [ +  + ]:             85 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       12170                 :              6 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12171                 :                :                                         "TYPE", qtypname,
                              12172                 :              6 :                                         tyinfo->dobj.namespace->dobj.name);
                              12173                 :                : 
 3491 sfrost@snowman.net      12174         [ +  - ]:             85 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12175                 :             85 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12176                 :             85 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12177                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12178                 :                :                                   .owner = tyinfo->rolname,
                              12179                 :                :                                   .description = "TYPE",
                              12180                 :                :                                   .section = SECTION_PRE_DATA,
                              12181                 :                :                                   .createStmt = q->data,
                              12182                 :                :                                   .dropStmt = delq->data));
                              12183                 :                : 
                              12184                 :                :     /* Dump Type Comments and Security Labels */
 3491 sfrost@snowman.net      12185         [ +  + ]:             85 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12186                 :             32 :         dumpComment(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12187                 :             32 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12188                 :             32 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12189                 :                : 
                              12190         [ -  + ]:             85 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       12191                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12192                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12193                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12194                 :                : 
 3491 sfrost@snowman.net      12195         [ +  + ]:CBC          85 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       12196                 :             32 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12197                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      12198                 :             32 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       12199                 :             32 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12200                 :                : 
 5107 heikki.linnakangas@i    12201                 :             85 :     PQclear(res);
                              12202                 :             85 :     destroyPQExpBuffer(q);
                              12203                 :             85 :     destroyPQExpBuffer(delq);
                              12204                 :             85 :     destroyPQExpBuffer(query);
 2800 tgl@sss.pgh.pa.us       12205                 :             85 :     free(qtypname);
                              12206                 :             85 :     free(qualtypname);
 5107 heikki.linnakangas@i    12207                 :             85 : }
                              12208                 :                : 
                              12209                 :                : /*
                              12210                 :                :  * dumpRangeType
                              12211                 :                :  *    writes out to fout the queries to recreate a user-defined range type
                              12212                 :                :  */
                              12213                 :                : static void
 1720 peter@eisentraut.org    12214                 :            112 : dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
                              12215                 :                : {
 3575 tgl@sss.pgh.pa.us       12216                 :            112 :     DumpOptions *dopt = fout->dopt;
 5107 heikki.linnakangas@i    12217                 :            112 :     PQExpBuffer q = createPQExpBuffer();
                              12218                 :            112 :     PQExpBuffer delq = createPQExpBuffer();
                              12219                 :            112 :     PQExpBuffer query = createPQExpBuffer();
                              12220                 :                :     PGresult   *res;
                              12221                 :                :     Oid         collationOid;
                              12222                 :                :     char       *qtypname;
                              12223                 :                :     char       *qualtypname;
                              12224                 :                :     char       *procname;
                              12225                 :                : 
 1421 tgl@sss.pgh.pa.us       12226         [ +  + ]:            112 :     if (!fout->is_prepared[PREPQUERY_DUMPRANGETYPE])
                              12227                 :                :     {
                              12228                 :                :         /* Set up query for range-specific details */
                              12229                 :             40 :         appendPQExpBufferStr(query,
                              12230                 :                :                              "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
                              12231                 :                : 
                              12232                 :             40 :         appendPQExpBufferStr(query,
                              12233                 :                :                              "SELECT ");
                              12234                 :                : 
                              12235         [ +  - ]:             40 :         if (fout->remoteVersion >= 140000)
                              12236                 :             40 :             appendPQExpBufferStr(query,
                              12237                 :                :                                  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
                              12238                 :                :         else
 1421 tgl@sss.pgh.pa.us       12239                 :UBC           0 :             appendPQExpBufferStr(query,
                              12240                 :                :                                  "NULL AS rngmultitype, ");
                              12241                 :                : 
 1421 tgl@sss.pgh.pa.us       12242                 :CBC          40 :         appendPQExpBufferStr(query,
                              12243                 :                :                              "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                              12244                 :                :                              "opc.opcname AS opcname, "
                              12245                 :                :                              "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
                              12246                 :                :                              "  WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
                              12247                 :                :                              "opc.opcdefault, "
                              12248                 :                :                              "CASE WHEN rngcollation = st.typcollation THEN 0 "
                              12249                 :                :                              "     ELSE rngcollation END AS collation, "
                              12250                 :                :                              "rngcanonical, rngsubdiff "
                              12251                 :                :                              "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
                              12252                 :                :                              "     pg_catalog.pg_opclass opc "
                              12253                 :                :                              "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
                              12254                 :                :                              "rngtypid = $1");
                              12255                 :                : 
                              12256                 :             40 :         ExecuteSqlStatement(fout, query->data);
                              12257                 :                : 
                              12258                 :             40 :         fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
                              12259                 :                :     }
                              12260                 :                : 
                              12261                 :            112 :     printfPQExpBuffer(query,
                              12262                 :                :                       "EXECUTE dumpRangeType('%u')",
 5107 heikki.linnakangas@i    12263                 :            112 :                       tyinfo->dobj.catId.oid);
                              12264                 :                : 
 5002 rhaas@postgresql.org    12265                 :            112 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12266                 :                : 
 4705 tgl@sss.pgh.pa.us       12267                 :            112 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12268                 :            112 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12269                 :                : 
                              12270                 :                :     /*
                              12271                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              12272                 :                :      * functions are generic and do not get dropped.
                              12273                 :                :      */
                              12274                 :            112 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12275                 :                : 
 4031 alvherre@alvh.no-ip.    12276         [ +  + ]:            112 :     if (dopt->binary_upgrade)
 2949 tgl@sss.pgh.pa.us       12277                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              12278                 :              8 :                                                  tyinfo->dobj.catId.oid,
                              12279                 :                :                                                  false, true);
                              12280                 :                : 
 5107 heikki.linnakangas@i    12281                 :            112 :     appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
                              12282                 :                :                       qualtypname);
                              12283                 :                : 
 5090 tgl@sss.pgh.pa.us       12284                 :            112 :     appendPQExpBuffer(q, "\n    subtype = %s",
                              12285                 :                :                       PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
                              12286                 :                : 
 1772 akorotkov@postgresql    12287         [ +  - ]:            112 :     if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
                              12288                 :            112 :         appendPQExpBuffer(q, ",\n    multirange_type_name = %s",
                              12289                 :                :                           PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
                              12290                 :                : 
                              12291                 :                :     /* print subtype_opclass only if not default for subtype */
 5090 tgl@sss.pgh.pa.us       12292         [ +  + ]:            112 :     if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
                              12293                 :                :     {
 4887 bruce@momjian.us        12294                 :             32 :         char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
                              12295                 :             32 :         char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
                              12296                 :                : 
 5090 tgl@sss.pgh.pa.us       12297                 :             32 :         appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                              12298                 :                :                           fmtId(nspname));
 4361 heikki.linnakangas@i    12299                 :             32 :         appendPQExpBufferStr(q, fmtId(opcname));
                              12300                 :                :     }
                              12301                 :                : 
 5090 tgl@sss.pgh.pa.us       12302                 :            112 :     collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
 5107 heikki.linnakangas@i    12303         [ +  + ]:            112 :     if (OidIsValid(collationOid))
                              12304                 :                :     {
 5090 tgl@sss.pgh.pa.us       12305                 :             37 :         CollInfo   *coll = findCollationByOid(collationOid);
                              12306                 :                : 
 5107 heikki.linnakangas@i    12307         [ +  - ]:             37 :         if (coll)
 2800 tgl@sss.pgh.pa.us       12308                 :             37 :             appendPQExpBuffer(q, ",\n    collation = %s",
                              12309                 :             37 :                               fmtQualifiedDumpable(coll));
                              12310                 :                :     }
                              12311                 :                : 
 5090                         12312                 :            112 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
                              12313         [ +  + ]:            112 :     if (strcmp(procname, "-") != 0)
                              12314                 :              9 :         appendPQExpBuffer(q, ",\n    canonical = %s", procname);
                              12315                 :                : 
                              12316                 :            112 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
                              12317         [ +  + ]:            112 :     if (strcmp(procname, "-") != 0)
                              12318                 :             23 :         appendPQExpBuffer(q, ",\n    subtype_diff = %s", procname);
                              12319                 :                : 
 4361 heikki.linnakangas@i    12320                 :            112 :     appendPQExpBufferStr(q, "\n);\n");
                              12321                 :                : 
 4031 alvherre@alvh.no-ip.    12322         [ +  + ]:            112 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       12323                 :              8 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12324                 :                :                                         "TYPE", qtypname,
                              12325                 :              8 :                                         tyinfo->dobj.namespace->dobj.name);
                              12326                 :                : 
 3491 sfrost@snowman.net      12327         [ +  - ]:            112 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12328                 :            112 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12329                 :            112 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12330                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12331                 :                :                                   .owner = tyinfo->rolname,
                              12332                 :                :                                   .description = "TYPE",
                              12333                 :                :                                   .section = SECTION_PRE_DATA,
                              12334                 :                :                                   .createStmt = q->data,
                              12335                 :                :                                   .dropStmt = delq->data));
                              12336                 :                : 
                              12337                 :                :     /* Dump Type Comments and Security Labels */
 3491 sfrost@snowman.net      12338         [ +  + ]:            112 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12339                 :             50 :         dumpComment(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12340                 :             50 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12341                 :             50 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12342                 :                : 
                              12343         [ -  + ]:            112 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       12344                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12345                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12346                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12347                 :                : 
 3491 sfrost@snowman.net      12348         [ +  + ]:CBC         112 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       12349                 :             32 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12350                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      12351                 :             32 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       12352                 :             32 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12353                 :                : 
 6783                         12354                 :            112 :     PQclear(res);
                              12355                 :            112 :     destroyPQExpBuffer(q);
                              12356                 :            112 :     destroyPQExpBuffer(delq);
                              12357                 :            112 :     destroyPQExpBuffer(query);
 2800                         12358                 :            112 :     free(qtypname);
                              12359                 :            112 :     free(qualtypname);
 7996                         12360                 :            112 : }
                              12361                 :                : 
                              12362                 :                : /*
                              12363                 :                :  * dumpUndefinedType
                              12364                 :                :  *    writes out to fout the queries to recreate a !typisdefined type
                              12365                 :                :  *
                              12366                 :                :  * This is a shell type, but we use different terminology to distinguish
                              12367                 :                :  * this case from where we have to emit a shell type definition to break
                              12368                 :                :  * circular dependencies.  An undefined type shouldn't ever have anything
                              12369                 :                :  * depending on it.
                              12370                 :                :  */
                              12371                 :                : static void
 1720 peter@eisentraut.org    12372                 :             37 : dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
                              12373                 :                : {
 3575 tgl@sss.pgh.pa.us       12374                 :             37 :     DumpOptions *dopt = fout->dopt;
 3737                         12375                 :             37 :     PQExpBuffer q = createPQExpBuffer();
                              12376                 :             37 :     PQExpBuffer delq = createPQExpBuffer();
                              12377                 :                :     char       *qtypname;
                              12378                 :                :     char       *qualtypname;
                              12379                 :                : 
                              12380                 :             37 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12381                 :             37 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12382                 :                : 
                              12383                 :             37 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12384                 :                : 
 3737                         12385         [ +  + ]:             37 :     if (dopt->binary_upgrade)
 2949                         12386                 :              2 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              12387                 :              2 :                                                  tyinfo->dobj.catId.oid,
                              12388                 :                :                                                  false, false);
                              12389                 :                : 
 3737                         12390                 :             37 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
                              12391                 :                :                       qualtypname);
                              12392                 :                : 
                              12393         [ +  + ]:             37 :     if (dopt->binary_upgrade)
 2800                         12394                 :              2 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12395                 :                :                                         "TYPE", qtypname,
                              12396                 :              2 :                                         tyinfo->dobj.namespace->dobj.name);
                              12397                 :                : 
 3491 sfrost@snowman.net      12398         [ +  - ]:             37 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12399                 :             37 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12400                 :             37 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12401                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12402                 :                :                                   .owner = tyinfo->rolname,
                              12403                 :                :                                   .description = "TYPE",
                              12404                 :                :                                   .section = SECTION_PRE_DATA,
                              12405                 :                :                                   .createStmt = q->data,
                              12406                 :                :                                   .dropStmt = delq->data));
                              12407                 :                : 
                              12408                 :                :     /* Dump Type Comments and Security Labels */
 3491 sfrost@snowman.net      12409         [ +  + ]:             37 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12410                 :             32 :         dumpComment(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12411                 :             32 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12412                 :             32 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12413                 :                : 
                              12414         [ -  + ]:             37 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       12415                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12416                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12417                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12418                 :                : 
 3491 sfrost@snowman.net      12419         [ -  + ]:CBC          37 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       12420                 :UBC           0 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12421                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      12422                 :              0 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       12423                 :              0 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12424                 :                : 
 3737 tgl@sss.pgh.pa.us       12425                 :CBC          37 :     destroyPQExpBuffer(q);
                              12426                 :             37 :     destroyPQExpBuffer(delq);
 2800                         12427                 :             37 :     free(qtypname);
                              12428                 :             37 :     free(qualtypname);
 3737                         12429                 :             37 : }
                              12430                 :                : 
                              12431                 :                : /*
                              12432                 :                :  * dumpBaseType
                              12433                 :                :  *    writes out to fout the queries to recreate a user-defined base type
                              12434                 :                :  */
                              12435                 :                : static void
 1720 peter@eisentraut.org    12436                 :            280 : dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
                              12437                 :                : {
 3575 tgl@sss.pgh.pa.us       12438                 :            280 :     DumpOptions *dopt = fout->dopt;
 8571                         12439                 :            280 :     PQExpBuffer q = createPQExpBuffer();
                              12440                 :            280 :     PQExpBuffer delq = createPQExpBuffer();
                              12441                 :            280 :     PQExpBuffer query = createPQExpBuffer();
                              12442                 :                :     PGresult   *res;
                              12443                 :                :     char       *qtypname;
                              12444                 :                :     char       *qualtypname;
                              12445                 :                :     char       *typlen;
                              12446                 :                :     char       *typinput;
                              12447                 :                :     char       *typoutput;
                              12448                 :                :     char       *typreceive;
                              12449                 :                :     char       *typsend;
                              12450                 :                :     char       *typmodin;
                              12451                 :                :     char       *typmodout;
                              12452                 :                :     char       *typanalyze;
                              12453                 :                :     char       *typsubscript;
                              12454                 :                :     Oid         typreceiveoid;
                              12455                 :                :     Oid         typsendoid;
                              12456                 :                :     Oid         typmodinoid;
                              12457                 :                :     Oid         typmodoutoid;
                              12458                 :                :     Oid         typanalyzeoid;
                              12459                 :                :     Oid         typsubscriptoid;
                              12460                 :                :     char       *typcategory;
                              12461                 :                :     char       *typispreferred;
                              12462                 :                :     char       *typdelim;
                              12463                 :                :     char       *typbyval;
                              12464                 :                :     char       *typalign;
                              12465                 :                :     char       *typstorage;
                              12466                 :                :     char       *typcollatable;
                              12467                 :                :     char       *typdefault;
 7188                         12468                 :            280 :     bool        typdefault_is_literal = false;
                              12469                 :                : 
 1421                         12470         [ +  + ]:            280 :     if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
                              12471                 :                :     {
                              12472                 :                :         /* Set up query for type-specific details */
 1786                         12473                 :             40 :         appendPQExpBufferStr(query,
                              12474                 :                :                              "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
                              12475                 :                :                              "SELECT typlen, "
                              12476                 :                :                              "typinput, typoutput, typreceive, typsend, "
                              12477                 :                :                              "typreceive::pg_catalog.oid AS typreceiveoid, "
                              12478                 :                :                              "typsend::pg_catalog.oid AS typsendoid, "
                              12479                 :                :                              "typanalyze, "
                              12480                 :                :                              "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                              12481                 :                :                              "typdelim, typbyval, typalign, typstorage, "
                              12482                 :                :                              "typmodin, typmodout, "
                              12483                 :                :                              "typmodin::pg_catalog.oid AS typmodinoid, "
                              12484                 :                :                              "typmodout::pg_catalog.oid AS typmodoutoid, "
                              12485                 :                :                              "typcategory, typispreferred, "
                              12486                 :                :                              "(typcollation <> 0) AS typcollatable, "
                              12487                 :                :                              "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
                              12488                 :                : 
 1421                         12489         [ +  - ]:             40 :         if (fout->remoteVersion >= 140000)
                              12490                 :             40 :             appendPQExpBufferStr(query,
                              12491                 :                :                                  "typsubscript, "
                              12492                 :                :                                  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
                              12493                 :                :         else
 1421 tgl@sss.pgh.pa.us       12494                 :UBC           0 :             appendPQExpBufferStr(query,
                              12495                 :                :                                  "'-' AS typsubscript, 0 AS typsubscriptoid ");
                              12496                 :                : 
 1421 tgl@sss.pgh.pa.us       12497                 :CBC          40 :         appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
                              12498                 :                :                              "WHERE oid = $1");
                              12499                 :                : 
                              12500                 :             40 :         ExecuteSqlStatement(fout, query->data);
                              12501                 :                : 
                              12502                 :             40 :         fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
                              12503                 :                :     }
                              12504                 :                : 
                              12505                 :            280 :     printfPQExpBuffer(query,
                              12506                 :                :                       "EXECUTE dumpBaseType('%u')",
 1786                         12507                 :            280 :                       tyinfo->dobj.catId.oid);
                              12508                 :                : 
 5002 rhaas@postgresql.org    12509                 :            280 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12510                 :                : 
 8571 tgl@sss.pgh.pa.us       12511                 :            280 :     typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
                              12512                 :            280 :     typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
                              12513                 :            280 :     typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
 8208                         12514                 :            280 :     typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
                              12515                 :            280 :     typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
 6876                         12516                 :            280 :     typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
                              12517                 :            280 :     typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
 7928                         12518                 :            280 :     typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
 1783                         12519                 :            280 :     typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
 7996                         12520                 :            280 :     typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
                              12521                 :            280 :     typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
 6876                         12522                 :            280 :     typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
                              12523                 :            280 :     typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
 7928                         12524                 :            280 :     typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
 1783                         12525                 :            280 :     typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
 6298                         12526                 :            280 :     typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
                              12527                 :            280 :     typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
 8571                         12528                 :            280 :     typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
                              12529                 :            280 :     typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
                              12530                 :            280 :     typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
                              12531                 :            280 :     typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
 5354 peter_e@gmx.net         12532                 :            280 :     typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
 7188 tgl@sss.pgh.pa.us       12533         [ -  + ]:            280 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
 7188 tgl@sss.pgh.pa.us       12534                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
 7188 tgl@sss.pgh.pa.us       12535         [ +  + ]:CBC         280 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              12536                 :                :     {
                              12537                 :             42 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6963 bruce@momjian.us        12538                 :             42 :         typdefault_is_literal = true;   /* it needs quotes */
                              12539                 :                :     }
                              12540                 :                :     else
 7188 tgl@sss.pgh.pa.us       12541                 :            238 :         typdefault = NULL;
                              12542                 :                : 
 4705                         12543                 :            280 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12544                 :            280 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12545                 :                : 
                              12546                 :                :     /*
                              12547                 :                :      * The reason we include CASCADE is that the circular dependency between
                              12548                 :                :      * the type and its I/O functions makes it impossible to drop the type any
                              12549                 :                :      * other way.
                              12550                 :                :      */
                              12551                 :            280 :     appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
                              12552                 :                : 
                              12553                 :                :     /*
                              12554                 :                :      * We might already have a shell type, but setting pg_type_oid is
                              12555                 :                :      * harmless, and in any case we'd better set the array type OID.
                              12556                 :                :      */
 4031 alvherre@alvh.no-ip.    12557         [ +  + ]:            280 :     if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    12558                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2949 tgl@sss.pgh.pa.us       12559                 :              8 :                                                  tyinfo->dobj.catId.oid,
                              12560                 :                :                                                  false, false);
                              12561                 :                : 
 8571                         12562                 :            280 :     appendPQExpBuffer(q,
                              12563                 :                :                       "CREATE TYPE %s (\n"
                              12564                 :                :                       "    INTERNALLENGTH = %s",
                              12565                 :                :                       qualtypname,
 8496 peter_e@gmx.net         12566         [ +  + ]:            280 :                       (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
                              12567                 :                : 
                              12568                 :                :     /* regproc result is sufficiently quoted already */
 3302 tgl@sss.pgh.pa.us       12569                 :            280 :     appendPQExpBuffer(q, ",\n    INPUT = %s", typinput);
                              12570                 :            280 :     appendPQExpBuffer(q, ",\n    OUTPUT = %s", typoutput);
                              12571         [ +  + ]:            280 :     if (OidIsValid(typreceiveoid))
                              12572                 :            207 :         appendPQExpBuffer(q, ",\n    RECEIVE = %s", typreceive);
                              12573         [ +  + ]:            280 :     if (OidIsValid(typsendoid))
                              12574                 :            207 :         appendPQExpBuffer(q, ",\n    SEND = %s", typsend);
                              12575         [ +  + ]:            280 :     if (OidIsValid(typmodinoid))
                              12576                 :             35 :         appendPQExpBuffer(q, ",\n    TYPMOD_IN = %s", typmodin);
                              12577         [ +  + ]:            280 :     if (OidIsValid(typmodoutoid))
                              12578                 :             35 :         appendPQExpBuffer(q, ",\n    TYPMOD_OUT = %s", typmodout);
                              12579         [ +  + ]:            280 :     if (OidIsValid(typanalyzeoid))
                              12580                 :              3 :         appendPQExpBuffer(q, ",\n    ANALYZE = %s", typanalyze);
                              12581                 :                : 
 5354 peter_e@gmx.net         12582         [ +  + ]:            280 :     if (strcmp(typcollatable, "t") == 0)
 4361 heikki.linnakangas@i    12583                 :             30 :         appendPQExpBufferStr(q, ",\n    COLLATABLE = true");
                              12584                 :                : 
 8571 tgl@sss.pgh.pa.us       12585         [ +  + ]:            280 :     if (typdefault != NULL)
                              12586                 :                :     {
 4361 heikki.linnakangas@i    12587                 :             42 :         appendPQExpBufferStr(q, ",\n    DEFAULT = ");
 7188 tgl@sss.pgh.pa.us       12588         [ +  - ]:             42 :         if (typdefault_is_literal)
 7092                         12589                 :             42 :             appendStringLiteralAH(q, typdefault, fout);
                              12590                 :                :         else
 7188 tgl@sss.pgh.pa.us       12591                 :UBC           0 :             appendPQExpBufferStr(q, typdefault);
                              12592                 :                :     }
                              12593                 :                : 
 1783 tgl@sss.pgh.pa.us       12594         [ +  + ]:CBC         280 :     if (OidIsValid(typsubscriptoid))
                              12595                 :             29 :         appendPQExpBuffer(q, ",\n    SUBSCRIPT = %s", typsubscript);
                              12596                 :                : 
 5787 bruce@momjian.us        12597         [ +  + ]:            280 :     if (OidIsValid(tyinfo->typelem))
 1510 tgl@sss.pgh.pa.us       12598                 :             26 :         appendPQExpBuffer(q, ",\n    ELEMENT = %s",
                              12599                 :             26 :                           getFormattedTypeName(fout, tyinfo->typelem,
                              12600                 :                :                                                zeroIsError));
                              12601                 :                : 
 6298                         12602         [ +  + ]:            280 :     if (strcmp(typcategory, "U") != 0)
                              12603                 :                :     {
 4361 heikki.linnakangas@i    12604                 :            158 :         appendPQExpBufferStr(q, ",\n    CATEGORY = ");
 6298 tgl@sss.pgh.pa.us       12605                 :            158 :         appendStringLiteralAH(q, typcategory, fout);
                              12606                 :                :     }
                              12607                 :                : 
                              12608         [ +  + ]:            280 :     if (strcmp(typispreferred, "t") == 0)
 4361 heikki.linnakangas@i    12609                 :             29 :         appendPQExpBufferStr(q, ",\n    PREFERRED = true");
                              12610                 :                : 
 8208 tgl@sss.pgh.pa.us       12611   [ +  -  +  + ]:            280 :     if (typdelim && strcmp(typdelim, ",") != 0)
                              12612                 :                :     {
 4361 heikki.linnakangas@i    12613                 :              3 :         appendPQExpBufferStr(q, ",\n    DELIMITER = ");
 7092 tgl@sss.pgh.pa.us       12614                 :              3 :         appendStringLiteralAH(q, typdelim, fout);
                              12615                 :                :     }
                              12616                 :                : 
 2063                         12617         [ +  + ]:            280 :     if (*typalign == TYPALIGN_CHAR)
 4361 heikki.linnakangas@i    12618                 :             12 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = char");
 2063 tgl@sss.pgh.pa.us       12619         [ +  + ]:            268 :     else if (*typalign == TYPALIGN_SHORT)
 4361 heikki.linnakangas@i    12620                 :              6 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int2");
 2063 tgl@sss.pgh.pa.us       12621         [ +  + ]:            262 :     else if (*typalign == TYPALIGN_INT)
 4361 heikki.linnakangas@i    12622                 :            187 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int4");
 2063 tgl@sss.pgh.pa.us       12623         [ +  - ]:             75 :     else if (*typalign == TYPALIGN_DOUBLE)
 4361 heikki.linnakangas@i    12624                 :             75 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = double");
                              12625                 :                : 
 2063 tgl@sss.pgh.pa.us       12626         [ +  + ]:            280 :     if (*typstorage == TYPSTORAGE_PLAIN)
 4361 heikki.linnakangas@i    12627                 :            205 :         appendPQExpBufferStr(q, ",\n    STORAGE = plain");
 2063 tgl@sss.pgh.pa.us       12628         [ -  + ]:             75 :     else if (*typstorage == TYPSTORAGE_EXTERNAL)
 4361 heikki.linnakangas@i    12629                 :UBC           0 :         appendPQExpBufferStr(q, ",\n    STORAGE = external");
 2063 tgl@sss.pgh.pa.us       12630         [ +  + ]:CBC          75 :     else if (*typstorage == TYPSTORAGE_EXTENDED)
 4361 heikki.linnakangas@i    12631                 :             66 :         appendPQExpBufferStr(q, ",\n    STORAGE = extended");
 2063 tgl@sss.pgh.pa.us       12632         [ +  - ]:              9 :     else if (*typstorage == TYPSTORAGE_MAIN)
 4361 heikki.linnakangas@i    12633                 :              9 :         appendPQExpBufferStr(q, ",\n    STORAGE = main");
                              12634                 :                : 
 8571 tgl@sss.pgh.pa.us       12635         [ +  + ]:            280 :     if (strcmp(typbyval, "t") == 0)
 4361 heikki.linnakangas@i    12636                 :            134 :         appendPQExpBufferStr(q, ",\n    PASSEDBYVALUE");
                              12637                 :                : 
                              12638                 :            280 :     appendPQExpBufferStr(q, "\n);\n");
                              12639                 :                : 
 4031 alvherre@alvh.no-ip.    12640         [ +  + ]:            280 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       12641                 :              8 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12642                 :                :                                         "TYPE", qtypname,
                              12643                 :              8 :                                         tyinfo->dobj.namespace->dobj.name);
                              12644                 :                : 
 3491 sfrost@snowman.net      12645         [ +  - ]:            280 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12646                 :            280 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12647                 :            280 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12648                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12649                 :                :                                   .owner = tyinfo->rolname,
                              12650                 :                :                                   .description = "TYPE",
                              12651                 :                :                                   .section = SECTION_PRE_DATA,
                              12652                 :                :                                   .createStmt = q->data,
                              12653                 :                :                                   .dropStmt = delq->data));
                              12654                 :                : 
                              12655                 :                :     /* Dump Type Comments and Security Labels */
 3491 sfrost@snowman.net      12656         [ +  + ]:            280 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12657                 :            245 :         dumpComment(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12658                 :            245 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12659                 :            245 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12660                 :                : 
                              12661         [ -  + ]:            280 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       12662                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      12663                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12664                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12665                 :                : 
 3491 sfrost@snowman.net      12666         [ +  + ]:CBC         280 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       12667                 :             32 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12668                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      12669                 :             32 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       12670                 :             32 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12671                 :                : 
 9414 bruce@momjian.us        12672                 :            280 :     PQclear(res);
 8571 tgl@sss.pgh.pa.us       12673                 :            280 :     destroyPQExpBuffer(q);
                              12674                 :            280 :     destroyPQExpBuffer(delq);
 8851                         12675                 :            280 :     destroyPQExpBuffer(query);
 2800                         12676                 :            280 :     free(qtypname);
                              12677                 :            280 :     free(qualtypname);
 9414 bruce@momjian.us        12678                 :            280 : }
                              12679                 :                : 
                              12680                 :                : /*
                              12681                 :                :  * dumpDomain
                              12682                 :                :  *    writes out to fout the queries to recreate a user-defined domain
                              12683                 :                :  */
                              12684                 :                : static void
 1720 peter@eisentraut.org    12685                 :            152 : dumpDomain(Archive *fout, const TypeInfo *tyinfo)
                              12686                 :                : {
 3575 tgl@sss.pgh.pa.us       12687                 :            152 :     DumpOptions *dopt = fout->dopt;
 8606 bruce@momjian.us        12688                 :            152 :     PQExpBuffer q = createPQExpBuffer();
                              12689                 :            152 :     PQExpBuffer delq = createPQExpBuffer();
                              12690                 :            152 :     PQExpBuffer query = createPQExpBuffer();
                              12691                 :                :     PGresult   *res;
                              12692                 :                :     int         i;
                              12693                 :                :     char       *qtypname;
                              12694                 :                :     char       *qualtypname;
                              12695                 :                :     char       *typnotnull;
                              12696                 :                :     char       *typdefn;
                              12697                 :                :     char       *typdefault;
                              12698                 :                :     Oid         typcollation;
 7188 tgl@sss.pgh.pa.us       12699                 :            152 :     bool        typdefault_is_literal = false;
                              12700                 :                : 
 1421                         12701         [ +  + ]:            152 :     if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
                              12702                 :                :     {
                              12703                 :                :         /* Set up query for domain-specific details */
                              12704                 :             37 :         appendPQExpBufferStr(query,
                              12705                 :                :                              "PREPARE dumpDomain(pg_catalog.oid) AS\n");
                              12706                 :                : 
 1413                         12707                 :             37 :         appendPQExpBufferStr(query, "SELECT t.typnotnull, "
                              12708                 :                :                              "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
                              12709                 :                :                              "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
                              12710                 :                :                              "t.typdefault, "
                              12711                 :                :                              "CASE WHEN t.typcollation <> u.typcollation "
                              12712                 :                :                              "THEN t.typcollation ELSE 0 END AS typcollation "
                              12713                 :                :                              "FROM pg_catalog.pg_type t "
                              12714                 :                :                              "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
                              12715                 :                :                              "WHERE t.oid = $1");
                              12716                 :                : 
 1421                         12717                 :             37 :         ExecuteSqlStatement(fout, query->data);
                              12718                 :                : 
                              12719                 :             37 :         fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
                              12720                 :                :     }
                              12721                 :                : 
                              12722                 :            152 :     printfPQExpBuffer(query,
                              12723                 :                :                       "EXECUTE dumpDomain('%u')",
                              12724                 :            152 :                       tyinfo->dobj.catId.oid);
                              12725                 :                : 
 5002 rhaas@postgresql.org    12726                 :            152 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12727                 :                : 
 8571 tgl@sss.pgh.pa.us       12728                 :            152 :     typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
                              12729                 :            152 :     typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
 7188                         12730         [ +  + ]:            152 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
                              12731                 :             37 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
                              12732         [ -  + ]:            115 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              12733                 :                :     {
 8553 tgl@sss.pgh.pa.us       12734                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6963 bruce@momjian.us        12735                 :              0 :         typdefault_is_literal = true;   /* it needs quotes */
                              12736                 :                :     }
                              12737                 :                :     else
 7188 tgl@sss.pgh.pa.us       12738                 :CBC         115 :         typdefault = NULL;
 5345                         12739                 :            152 :     typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
                              12740                 :                : 
 4031 alvherre@alvh.no-ip.    12741         [ +  + ]:            152 :     if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    12742                 :             25 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2949 tgl@sss.pgh.pa.us       12743                 :             25 :                                                  tyinfo->dobj.catId.oid,
                              12744                 :                :                                                  true,  /* force array type */
                              12745                 :                :                                                  false);    /* force multirange type */
                              12746                 :                : 
 4705                         12747                 :            152 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12748                 :            152 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12749                 :                : 
 8606 bruce@momjian.us        12750                 :            152 :     appendPQExpBuffer(q,
                              12751                 :                :                       "CREATE DOMAIN %s AS %s",
                              12752                 :                :                       qualtypname,
                              12753                 :                :                       typdefn);
                              12754                 :                : 
                              12755                 :                :     /* Print collation only if different from base type's collation */
 5345 tgl@sss.pgh.pa.us       12756         [ +  + ]:            152 :     if (OidIsValid(typcollation))
                              12757                 :                :     {
                              12758                 :                :         CollInfo   *coll;
                              12759                 :                : 
                              12760                 :             32 :         coll = findCollationByOid(typcollation);
                              12761         [ +  - ]:             32 :         if (coll)
 2800                         12762                 :             32 :             appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
                              12763                 :                :     }
                              12764                 :                : 
                              12765                 :                :     /*
                              12766                 :                :      * Print a not-null constraint if there's one.  In servers older than 17
                              12767                 :                :      * these don't have names, so just print it unadorned; in newer ones they
                              12768                 :                :      * do, but most of the time it's going to be the standard generated one,
                              12769                 :                :      * so omit the name in that case also.
                              12770                 :                :      */
 8571                         12771         [ +  + ]:            152 :     if (typnotnull[0] == 't')
                              12772                 :                :     {
   98 alvherre@kurilemu.de    12773   [ +  -  -  + ]:             47 :         if (fout->remoteVersion < 170000 || tyinfo->notnull == NULL)
   98 alvherre@kurilemu.de    12774                 :UBC           0 :             appendPQExpBufferStr(q, " NOT NULL");
                              12775                 :                :         else
                              12776                 :                :         {
   98 alvherre@kurilemu.de    12777                 :CBC          47 :             ConstraintInfo *notnull = tyinfo->notnull;
                              12778                 :                : 
                              12779         [ +  - ]:             47 :             if (!notnull->separate)
                              12780                 :                :             {
                              12781                 :                :                 char       *default_name;
                              12782                 :                : 
                              12783                 :                :                 /* XXX should match ChooseConstraintName better */
                              12784                 :             47 :                 default_name = psprintf("%s_not_null", tyinfo->dobj.name);
                              12785                 :                : 
                              12786         [ +  + ]:             47 :                 if (strcmp(default_name, notnull->dobj.name) == 0)
                              12787                 :             15 :                     appendPQExpBufferStr(q, " NOT NULL");
                              12788                 :                :                 else
                              12789                 :             32 :                     appendPQExpBuffer(q, " CONSTRAINT %s %s",
                              12790                 :             32 :                                       fmtId(notnull->dobj.name), notnull->condef);
                              12791                 :             47 :                 free(default_name);
                              12792                 :                :             }
                              12793                 :                :         }
                              12794                 :                :     }
                              12795                 :                : 
 7188 tgl@sss.pgh.pa.us       12796         [ +  + ]:            152 :     if (typdefault != NULL)
                              12797                 :                :     {
 4361 heikki.linnakangas@i    12798                 :             37 :         appendPQExpBufferStr(q, " DEFAULT ");
 7188 tgl@sss.pgh.pa.us       12799         [ -  + ]:             37 :         if (typdefault_is_literal)
 7092 tgl@sss.pgh.pa.us       12800                 :UBC           0 :             appendStringLiteralAH(q, typdefault, fout);
                              12801                 :                :         else
 7188 tgl@sss.pgh.pa.us       12802                 :CBC          37 :             appendPQExpBufferStr(q, typdefault);
                              12803                 :                :     }
                              12804                 :                : 
 8355                         12805                 :            152 :     PQclear(res);
                              12806                 :                : 
                              12807                 :                :     /*
                              12808                 :                :      * Add any CHECK constraints for the domain
                              12809                 :                :      */
 5787 bruce@momjian.us        12810         [ +  + ]:            259 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              12811                 :                :     {
                              12812                 :            107 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
                              12813                 :                : 
   98 alvherre@kurilemu.de    12814   [ +  +  +  - ]:            107 :         if (!domcheck->separate && domcheck->contype == 'c')
 7996 tgl@sss.pgh.pa.us       12815                 :            102 :             appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
 7317 bruce@momjian.us        12816                 :            102 :                               fmtId(domcheck->dobj.name), domcheck->condef);
                              12817                 :                :     }
                              12818                 :                : 
 4361 heikki.linnakangas@i    12819                 :            152 :     appendPQExpBufferStr(q, ";\n");
                              12820                 :                : 
 2800 tgl@sss.pgh.pa.us       12821                 :            152 :     appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
                              12822                 :                : 
 4031 alvherre@alvh.no-ip.    12823         [ +  + ]:            152 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       12824                 :             25 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12825                 :                :                                         "DOMAIN", qtypname,
                              12826                 :             25 :                                         tyinfo->dobj.namespace->dobj.name);
                              12827                 :                : 
 3491 sfrost@snowman.net      12828         [ +  - ]:            152 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12829                 :            152 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    12830                 :            152 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12831                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12832                 :                :                                   .owner = tyinfo->rolname,
                              12833                 :                :                                   .description = "DOMAIN",
                              12834                 :                :                                   .section = SECTION_PRE_DATA,
                              12835                 :                :                                   .createStmt = q->data,
                              12836                 :                :                                   .dropStmt = delq->data));
                              12837                 :                : 
                              12838                 :                :     /* Dump Domain Comments and Security Labels */
 3491 sfrost@snowman.net      12839         [ -  + ]:            152 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       12840                 :UBC           0 :         dumpComment(fout, "DOMAIN", qtypname,
 3491 sfrost@snowman.net      12841                 :              0 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12842                 :              0 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12843                 :                : 
 3491 sfrost@snowman.net      12844         [ -  + ]:CBC         152 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       12845                 :UBC           0 :         dumpSecLabel(fout, "DOMAIN", qtypname,
 3491 sfrost@snowman.net      12846                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12847                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12848                 :                : 
 3491 sfrost@snowman.net      12849         [ +  + ]:CBC         152 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       12850                 :             32 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12851                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      12852                 :             32 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       12853                 :             32 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12854                 :                : 
                              12855                 :                :     /* Dump any per-constraint comments */
 3961 alvherre@alvh.no-ip.    12856         [ +  + ]:            259 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              12857                 :                :     {
                              12858                 :            107 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
                              12859                 :                :         PQExpBuffer conprefix;
                              12860                 :                : 
                              12861                 :                :         /* but only if the constraint itself was dumped here */
  103 alvherre@kurilemu.de    12862         [ +  + ]:            107 :         if (domcheck->separate)
                              12863                 :              5 :             continue;
                              12864                 :                : 
                              12865                 :            102 :         conprefix = createPQExpBuffer();
 2800 tgl@sss.pgh.pa.us       12866                 :            102 :         appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
 3961 alvherre@alvh.no-ip.    12867                 :            102 :                           fmtId(domcheck->dobj.name));
                              12868                 :                : 
 1090 tgl@sss.pgh.pa.us       12869         [ +  + ]:            102 :         if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800                         12870                 :             32 :             dumpComment(fout, conprefix->data, qtypname,
 3491 sfrost@snowman.net      12871                 :             32 :                         tyinfo->dobj.namespace->dobj.name,
                              12872                 :             32 :                         tyinfo->rolname,
                              12873                 :             32 :                         domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12874                 :                : 
 2800 tgl@sss.pgh.pa.us       12875                 :            102 :         destroyPQExpBuffer(conprefix);
                              12876                 :                :     }
                              12877                 :                : 
                              12878                 :                :     /*
                              12879                 :                :      * And a comment on the not-null constraint, if there's one -- but only if
                              12880                 :                :      * the constraint itself was dumped here
                              12881                 :                :      */
   98 alvherre@kurilemu.de    12882   [ +  +  +  - ]:            152 :     if (tyinfo->notnull != NULL && !tyinfo->notnull->separate)
                              12883                 :                :     {
                              12884                 :             47 :         PQExpBuffer conprefix = createPQExpBuffer();
                              12885                 :                : 
                              12886                 :             47 :         appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
                              12887                 :             47 :                           fmtId(tyinfo->notnull->dobj.name));
                              12888                 :                : 
                              12889         [ +  + ]:             47 :         if (tyinfo->notnull->dobj.dump & DUMP_COMPONENT_COMMENT)
                              12890                 :             32 :             dumpComment(fout, conprefix->data, qtypname,
                              12891                 :             32 :                         tyinfo->dobj.namespace->dobj.name,
                              12892                 :             32 :                         tyinfo->rolname,
                              12893                 :             32 :                         tyinfo->notnull->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12894                 :             47 :         destroyPQExpBuffer(conprefix);
                              12895                 :                :     }
                              12896                 :                : 
 8571 tgl@sss.pgh.pa.us       12897                 :            152 :     destroyPQExpBuffer(q);
                              12898                 :            152 :     destroyPQExpBuffer(delq);
                              12899                 :            152 :     destroyPQExpBuffer(query);
 2800                         12900                 :            152 :     free(qtypname);
                              12901                 :            152 :     free(qualtypname);
 8606 bruce@momjian.us        12902                 :            152 : }
                              12903                 :                : 
                              12904                 :                : /*
                              12905                 :                :  * dumpCompositeType
                              12906                 :                :  *    writes out to fout the queries to recreate a user-defined stand-alone
                              12907                 :                :  *    composite type
                              12908                 :                :  */
                              12909                 :                : static void
 1720 peter@eisentraut.org    12910                 :            130 : dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
                              12911                 :                : {
 3575 tgl@sss.pgh.pa.us       12912                 :            130 :     DumpOptions *dopt = fout->dopt;
 8474 bruce@momjian.us        12913                 :            130 :     PQExpBuffer q = createPQExpBuffer();
 5273 heikki.linnakangas@i    12914                 :            130 :     PQExpBuffer dropped = createPQExpBuffer();
 8474 bruce@momjian.us        12915                 :            130 :     PQExpBuffer delq = createPQExpBuffer();
                              12916                 :            130 :     PQExpBuffer query = createPQExpBuffer();
                              12917                 :                :     PGresult   *res;
                              12918                 :                :     char       *qtypname;
                              12919                 :                :     char       *qualtypname;
                              12920                 :                :     int         ntups;
                              12921                 :                :     int         i_attname;
                              12922                 :                :     int         i_atttypdefn;
                              12923                 :                :     int         i_attlen;
                              12924                 :                :     int         i_attalign;
                              12925                 :                :     int         i_attisdropped;
                              12926                 :                :     int         i_attcollation;
                              12927                 :                :     int         i;
                              12928                 :                :     int         actual_atts;
                              12929                 :                : 
 1421 tgl@sss.pgh.pa.us       12930         [ +  + ]:            130 :     if (!fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE])
                              12931                 :                :     {
                              12932                 :                :         /*
                              12933                 :                :          * Set up query for type-specific details.
                              12934                 :                :          *
                              12935                 :                :          * Since we only want to dump COLLATE clauses for attributes whose
                              12936                 :                :          * collation is different from their type's default, we use a CASE
                              12937                 :                :          * here to suppress uninteresting attcollations cheaply.  atttypid
                              12938                 :                :          * will be 0 for dropped columns; collation does not matter for those.
                              12939                 :                :          */
                              12940                 :             55 :         appendPQExpBufferStr(query,
                              12941                 :                :                              "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
                              12942                 :                :                              "SELECT a.attname, a.attnum, "
                              12943                 :                :                              "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
                              12944                 :                :                              "a.attlen, a.attalign, a.attisdropped, "
                              12945                 :                :                              "CASE WHEN a.attcollation <> at.typcollation "
                              12946                 :                :                              "THEN a.attcollation ELSE 0 END AS attcollation "
                              12947                 :                :                              "FROM pg_catalog.pg_type ct "
                              12948                 :                :                              "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
                              12949                 :                :                              "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
                              12950                 :                :                              "WHERE ct.oid = $1 "
                              12951                 :                :                              "ORDER BY a.attnum");
                              12952                 :                : 
                              12953                 :             55 :         ExecuteSqlStatement(fout, query->data);
                              12954                 :                : 
                              12955                 :             55 :         fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE] = true;
                              12956                 :                :     }
                              12957                 :                : 
                              12958                 :            130 :     printfPQExpBuffer(query,
                              12959                 :                :                       "EXECUTE dumpCompositeType('%u')",
                              12960                 :            130 :                       tyinfo->dobj.catId.oid);
                              12961                 :                : 
 5011 rhaas@postgresql.org    12962                 :            130 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              12963                 :                : 
 8474 bruce@momjian.us        12964                 :            130 :     ntups = PQntuples(res);
                              12965                 :                : 
 8460 tgl@sss.pgh.pa.us       12966                 :            130 :     i_attname = PQfnumber(res, "attname");
                              12967                 :            130 :     i_atttypdefn = PQfnumber(res, "atttypdefn");
 5273 heikki.linnakangas@i    12968                 :            130 :     i_attlen = PQfnumber(res, "attlen");
                              12969                 :            130 :     i_attalign = PQfnumber(res, "attalign");
                              12970                 :            130 :     i_attisdropped = PQfnumber(res, "attisdropped");
 5307 tgl@sss.pgh.pa.us       12971                 :            130 :     i_attcollation = PQfnumber(res, "attcollation");
                              12972                 :                : 
 4031 alvherre@alvh.no-ip.    12973         [ +  + ]:            130 :     if (dopt->binary_upgrade)
                              12974                 :                :     {
 5011 rhaas@postgresql.org    12975                 :             18 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2949 tgl@sss.pgh.pa.us       12976                 :             18 :                                                  tyinfo->dobj.catId.oid,
                              12977                 :                :                                                  false, false);
  481 nathan@postgresql.or    12978                 :             18 :         binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid);
                              12979                 :                :     }
                              12980                 :                : 
 4705 tgl@sss.pgh.pa.us       12981                 :            130 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2800                         12982                 :            130 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12983                 :                : 
 8460                         12984                 :            130 :     appendPQExpBuffer(q, "CREATE TYPE %s AS (",
                              12985                 :                :                       qualtypname);
                              12986                 :                : 
 5273 heikki.linnakangas@i    12987                 :            130 :     actual_atts = 0;
 8474 bruce@momjian.us        12988         [ +  + ]:            412 :     for (i = 0; i < ntups; i++)
                              12989                 :                :     {
                              12990                 :                :         char       *attname;
                              12991                 :                :         char       *atttypdefn;
                              12992                 :                :         char       *attlen;
                              12993                 :                :         char       *attalign;
                              12994                 :                :         bool        attisdropped;
                              12995                 :                :         Oid         attcollation;
                              12996                 :                : 
 8460 tgl@sss.pgh.pa.us       12997                 :            282 :         attname = PQgetvalue(res, i, i_attname);
                              12998                 :            282 :         atttypdefn = PQgetvalue(res, i, i_atttypdefn);
 5273 heikki.linnakangas@i    12999                 :            282 :         attlen = PQgetvalue(res, i, i_attlen);
                              13000                 :            282 :         attalign = PQgetvalue(res, i, i_attalign);
                              13001                 :            282 :         attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
 5307 tgl@sss.pgh.pa.us       13002                 :            282 :         attcollation = atooid(PQgetvalue(res, i, i_attcollation));
                              13003                 :                : 
 4031 alvherre@alvh.no-ip.    13004   [ +  +  +  + ]:            282 :         if (attisdropped && !dopt->binary_upgrade)
 5273 heikki.linnakangas@i    13005                 :              8 :             continue;
                              13006                 :                : 
                              13007                 :                :         /* Format properly if not first attr */
                              13008         [ +  + ]:            274 :         if (actual_atts++ > 0)
 4361                         13009                 :            144 :             appendPQExpBufferChar(q, ',');
                              13010                 :            274 :         appendPQExpBufferStr(q, "\n\t");
                              13011                 :                : 
 5273                         13012         [ +  + ]:            274 :         if (!attisdropped)
                              13013                 :                :         {
                              13014                 :            272 :             appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
                              13015                 :                : 
                              13016                 :                :             /* Add collation if not default for the column type */
                              13017         [ -  + ]:            272 :             if (OidIsValid(attcollation))
                              13018                 :                :             {
                              13019                 :                :                 CollInfo   *coll;
                              13020                 :                : 
 5273 heikki.linnakangas@i    13021                 :UBC           0 :                 coll = findCollationByOid(attcollation);
                              13022         [ #  # ]:              0 :                 if (coll)
 2800 tgl@sss.pgh.pa.us       13023                 :              0 :                     appendPQExpBuffer(q, " COLLATE %s",
                              13024                 :              0 :                                       fmtQualifiedDumpable(coll));
                              13025                 :                :             }
                              13026                 :                :         }
                              13027                 :                :         else
                              13028                 :                :         {
                              13029                 :                :             /*
                              13030                 :                :              * This is a dropped attribute and we're in binary_upgrade mode.
                              13031                 :                :              * Insert a placeholder for it in the CREATE TYPE command, and set
                              13032                 :                :              * length and alignment with direct UPDATE to the catalogs
                              13033                 :                :              * afterwards. See similar code in dumpTableSchema().
                              13034                 :                :              */
 5273 heikki.linnakangas@i    13035                 :CBC           2 :             appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
                              13036                 :                : 
                              13037                 :                :             /* stash separately for insertion after the CREATE TYPE */
 4361                         13038                 :              2 :             appendPQExpBufferStr(dropped,
                              13039                 :                :                                  "\n-- For binary upgrade, recreate dropped column.\n");
 5273                         13040                 :              2 :             appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
                              13041                 :                :                               "SET attlen = %s, "
                              13042                 :                :                               "attalign = '%s', attbyval = false\n"
                              13043                 :                :                               "WHERE attname = ", attlen, attalign);
                              13044                 :              2 :             appendStringLiteralAH(dropped, attname, fout);
 4361                         13045                 :              2 :             appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
 2800 tgl@sss.pgh.pa.us       13046                 :              2 :             appendStringLiteralAH(dropped, qualtypname, fout);
 4361 heikki.linnakangas@i    13047                 :              2 :             appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
                              13048                 :                : 
 5273                         13049                 :              2 :             appendPQExpBuffer(dropped, "ALTER TYPE %s ",
                              13050                 :                :                               qualtypname);
                              13051                 :              2 :             appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                              13052                 :                :                               fmtId(attname));
                              13053                 :                :         }
                              13054                 :                :     }
 4361                         13055                 :            130 :     appendPQExpBufferStr(q, "\n);\n");
 5273                         13056                 :            130 :     appendPQExpBufferStr(q, dropped->data);
                              13057                 :                : 
 2800 tgl@sss.pgh.pa.us       13058                 :            130 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              13059                 :                : 
 4031 alvherre@alvh.no-ip.    13060         [ +  + ]:            130 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       13061                 :             18 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              13062                 :                :                                         "TYPE", qtypname,
                              13063                 :             18 :                                         tyinfo->dobj.namespace->dobj.name);
                              13064                 :                : 
 3491 sfrost@snowman.net      13065         [ +  + ]:            130 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13066                 :            113 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    13067                 :            113 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              13068                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              13069                 :                :                                   .owner = tyinfo->rolname,
                              13070                 :                :                                   .description = "TYPE",
                              13071                 :                :                                   .section = SECTION_PRE_DATA,
                              13072                 :                :                                   .createStmt = q->data,
                              13073                 :                :                                   .dropStmt = delq->data));
                              13074                 :                : 
                              13075                 :                : 
                              13076                 :                :     /* Dump Type Comments and Security Labels */
 3491 sfrost@snowman.net      13077         [ +  + ]:            130 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       13078                 :             32 :         dumpComment(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      13079                 :             32 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              13080                 :             32 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              13081                 :                : 
                              13082         [ -  + ]:            130 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       13083                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3491 sfrost@snowman.net      13084                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              13085                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              13086                 :                : 
 3491 sfrost@snowman.net      13087         [ +  + ]:CBC         130 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       13088                 :             18 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              13089                 :                :                 qtypname, NULL,
 3491 sfrost@snowman.net      13090                 :             18 :                 tyinfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       13091                 :             18 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              13092                 :                : 
                              13093                 :                :     /* Dump any per-column comments */
 1397                         13094         [ +  + ]:            130 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              13095                 :             32 :         dumpCompositeTypeColComments(fout, tyinfo, res);
                              13096                 :                : 
 7996                         13097                 :            130 :     PQclear(res);
                              13098                 :            130 :     destroyPQExpBuffer(q);
 5273 heikki.linnakangas@i    13099                 :            130 :     destroyPQExpBuffer(dropped);
 7996 tgl@sss.pgh.pa.us       13100                 :            130 :     destroyPQExpBuffer(delq);
                              13101                 :            130 :     destroyPQExpBuffer(query);
 2800                         13102                 :            130 :     free(qtypname);
                              13103                 :            130 :     free(qualtypname);
 5940                         13104                 :            130 : }
                              13105                 :                : 
                              13106                 :                : /*
                              13107                 :                :  * dumpCompositeTypeColComments
                              13108                 :                :  *    writes out to fout the queries to recreate comments on the columns of
                              13109                 :                :  *    a user-defined stand-alone composite type.
                              13110                 :                :  *
                              13111                 :                :  * The caller has already made a query to collect the names and attnums
                              13112                 :                :  * of the type's columns, so we just pass that result into here rather
                              13113                 :                :  * than reading them again.
                              13114                 :                :  */
                              13115                 :                : static void
 1397                         13116                 :             32 : dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
                              13117                 :                :                              PGresult *res)
                              13118                 :                : {
                              13119                 :                :     CommentItem *comments;
                              13120                 :                :     int         ncomments;
                              13121                 :                :     PQExpBuffer query;
                              13122                 :                :     PQExpBuffer target;
                              13123                 :                :     int         i;
                              13124                 :                :     int         ntups;
                              13125                 :                :     int         i_attname;
                              13126                 :                :     int         i_attnum;
                              13127                 :                :     int         i_attisdropped;
                              13128                 :                : 
                              13129                 :                :     /* do nothing, if --no-comments is supplied */
 2832                         13130         [ -  + ]:             32 :     if (fout->dopt->no_comments)
 2832 tgl@sss.pgh.pa.us       13131                 :UBC           0 :         return;
                              13132                 :                : 
                              13133                 :                :     /* Search for comments associated with type's pg_class OID */
 1397 tgl@sss.pgh.pa.us       13134                 :CBC          32 :     ncomments = findComments(RelationRelationId, tyinfo->typrelid,
                              13135                 :                :                              &comments);
                              13136                 :                : 
                              13137                 :                :     /* If no comments exist, we're done */
 5940                         13138         [ -  + ]:             32 :     if (ncomments <= 0)
 5940 tgl@sss.pgh.pa.us       13139                 :UBC           0 :         return;
                              13140                 :                : 
                              13141                 :                :     /* Build COMMENT ON statements */
 1397 tgl@sss.pgh.pa.us       13142                 :CBC          32 :     query = createPQExpBuffer();
 5940                         13143                 :             32 :     target = createPQExpBuffer();
                              13144                 :                : 
 1397                         13145                 :             32 :     ntups = PQntuples(res);
 5940                         13146                 :             32 :     i_attnum = PQfnumber(res, "attnum");
                              13147                 :             32 :     i_attname = PQfnumber(res, "attname");
 1397                         13148                 :             32 :     i_attisdropped = PQfnumber(res, "attisdropped");
 5940                         13149         [ +  + ]:             64 :     while (ncomments > 0)
                              13150                 :                :     {
                              13151                 :                :         const char *attname;
                              13152                 :                : 
                              13153                 :             32 :         attname = NULL;
                              13154         [ +  - ]:             32 :         for (i = 0; i < ntups; i++)
                              13155                 :                :         {
 1397                         13156         [ +  - ]:             32 :             if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
                              13157         [ +  - ]:             32 :                 PQgetvalue(res, i, i_attisdropped)[0] != 't')
                              13158                 :                :             {
 5940                         13159                 :             32 :                 attname = PQgetvalue(res, i, i_attname);
                              13160                 :             32 :                 break;
                              13161                 :                :             }
                              13162                 :                :         }
                              13163         [ +  - ]:             32 :         if (attname)            /* just in case we don't find it */
                              13164                 :                :         {
                              13165                 :             32 :             const char *descr = comments->descr;
                              13166                 :                : 
                              13167                 :             32 :             resetPQExpBuffer(target);
                              13168                 :             32 :             appendPQExpBuffer(target, "COLUMN %s.",
 5787 bruce@momjian.us        13169                 :             32 :                               fmtId(tyinfo->dobj.name));
 4361 heikki.linnakangas@i    13170                 :             32 :             appendPQExpBufferStr(target, fmtId(attname));
                              13171                 :                : 
 5940 tgl@sss.pgh.pa.us       13172                 :             32 :             resetPQExpBuffer(query);
 2800                         13173                 :             32 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              13174                 :             32 :                               fmtQualifiedDumpable(tyinfo));
                              13175                 :             32 :             appendPQExpBuffer(query, "%s IS ", fmtId(attname));
 5940                         13176                 :             32 :             appendStringLiteralAH(query, descr, fout);
 4361 heikki.linnakangas@i    13177                 :             32 :             appendPQExpBufferStr(query, ";\n");
                              13178                 :                : 
 5940 tgl@sss.pgh.pa.us       13179                 :             32 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    13180                 :             32 :                          ARCHIVE_OPTS(.tag = target->data,
                              13181                 :                :                                       .namespace = tyinfo->dobj.namespace->dobj.name,
                              13182                 :                :                                       .owner = tyinfo->rolname,
                              13183                 :                :                                       .description = "COMMENT",
                              13184                 :                :                                       .section = SECTION_NONE,
                              13185                 :                :                                       .createStmt = query->data,
                              13186                 :                :                                       .deps = &(tyinfo->dobj.dumpId),
                              13187                 :                :                                       .nDeps = 1));
                              13188                 :                :         }
                              13189                 :                : 
 5940 tgl@sss.pgh.pa.us       13190                 :             32 :         comments++;
                              13191                 :             32 :         ncomments--;
                              13192                 :                :     }
                              13193                 :                : 
                              13194                 :             32 :     destroyPQExpBuffer(query);
                              13195                 :             32 :     destroyPQExpBuffer(target);
                              13196                 :                : }
                              13197                 :                : 
                              13198                 :                : /*
                              13199                 :                :  * dumpShellType
                              13200                 :                :  *    writes out to fout the queries to create a shell type
                              13201                 :                :  *
                              13202                 :                :  * We dump a shell definition in advance of the I/O functions for the type.
                              13203                 :                :  */
                              13204                 :                : static void
 1720 peter@eisentraut.org    13205                 :             73 : dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
                              13206                 :                : {
 3575 tgl@sss.pgh.pa.us       13207                 :             73 :     DumpOptions *dopt = fout->dopt;
                              13208                 :                :     PQExpBuffer q;
                              13209                 :                : 
                              13210                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    13211         [ +  + ]:             73 :     if (!dopt->dumpSchema)
 7179 tgl@sss.pgh.pa.us       13212                 :              6 :         return;
                              13213                 :                : 
                              13214                 :             67 :     q = createPQExpBuffer();
                              13215                 :                : 
                              13216                 :                :     /*
                              13217                 :                :      * Note the lack of a DROP command for the shell type; any required DROP
                              13218                 :                :      * is driven off the base type entry, instead.  This interacts with
                              13219                 :                :      * _printTocEntry()'s use of the presence of a DROP command to decide
                              13220                 :                :      * whether an entry needs an ALTER OWNER command.  We don't want to alter
                              13221                 :                :      * the shell type's owner immediately on creation; that should happen only
                              13222                 :                :      * after it's filled in, otherwise the backend complains.
                              13223                 :                :      */
                              13224                 :                : 
 4031 alvherre@alvh.no-ip.    13225         [ +  + ]:             67 :     if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    13226                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2949 tgl@sss.pgh.pa.us       13227                 :              8 :                                                  stinfo->baseType->dobj.catId.oid,
                              13228                 :                :                                                  false, false);
                              13229                 :                : 
 7179                         13230                 :             67 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
 2800                         13231                 :             67 :                       fmtQualifiedDumpable(stinfo));
                              13232                 :                : 
 3491 sfrost@snowman.net      13233         [ +  - ]:             67 :     if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13234                 :             67 :         ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    13235                 :             67 :                      ARCHIVE_OPTS(.tag = stinfo->dobj.name,
                              13236                 :                :                                   .namespace = stinfo->dobj.namespace->dobj.name,
                              13237                 :                :                                   .owner = stinfo->baseType->rolname,
                              13238                 :                :                                   .description = "SHELL TYPE",
                              13239                 :                :                                   .section = SECTION_PRE_DATA,
                              13240                 :                :                                   .createStmt = q->data));
                              13241                 :                : 
 7179 tgl@sss.pgh.pa.us       13242                 :             67 :     destroyPQExpBuffer(q);
                              13243                 :                : }
                              13244                 :                : 
                              13245                 :                : /*
                              13246                 :                :  * dumpProcLang
                              13247                 :                :  *        writes out to fout the queries to recreate a user-defined
                              13248                 :                :  *        procedural language
                              13249                 :                :  */
                              13250                 :                : static void
 1720 peter@eisentraut.org    13251                 :             82 : dumpProcLang(Archive *fout, const ProcLangInfo *plang)
                              13252                 :                : {
 3575 tgl@sss.pgh.pa.us       13253                 :             82 :     DumpOptions *dopt = fout->dopt;
                              13254                 :                :     PQExpBuffer defqry;
                              13255                 :                :     PQExpBuffer delqry;
                              13256                 :                :     bool        useParams;
                              13257                 :                :     char       *qlanname;
                              13258                 :                :     FuncInfo   *funcInfo;
 5879                         13259                 :             82 :     FuncInfo   *inlineInfo = NULL;
 7996                         13260                 :             82 :     FuncInfo   *validatorInfo = NULL;
                              13261                 :                : 
                              13262                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    13263         [ +  + ]:             82 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       13264                 :             13 :         return;
                              13265                 :                : 
                              13266                 :                :     /*
                              13267                 :                :      * Try to find the support function(s).  It is not an error if we don't
                              13268                 :                :      * find them --- if the functions are in the pg_catalog schema, as is
                              13269                 :                :      * standard in 8.1 and up, then we won't have loaded them. (In this case
                              13270                 :                :      * we will emit a parameterless CREATE LANGUAGE command, which will
                              13271                 :                :      * require PL template knowledge in the backend to reload.)
                              13272                 :                :      */
                              13273                 :                : 
                              13274                 :             69 :     funcInfo = findFuncByOid(plang->lanplcallfoid);
 7179                         13275   [ +  +  +  + ]:             69 :     if (funcInfo != NULL && !funcInfo->dobj.dump)
 7357                         13276                 :              2 :         funcInfo = NULL;        /* treat not-dumped same as not-found */
                              13277                 :                : 
 5879                         13278         [ +  + ]:             69 :     if (OidIsValid(plang->laninline))
                              13279                 :                :     {
                              13280                 :             38 :         inlineInfo = findFuncByOid(plang->laninline);
                              13281   [ +  +  +  - ]:             38 :         if (inlineInfo != NULL && !inlineInfo->dobj.dump)
                              13282                 :              1 :             inlineInfo = NULL;
                              13283                 :                :     }
                              13284                 :                : 
 7996                         13285         [ +  + ]:             69 :     if (OidIsValid(plang->lanvalidator))
                              13286                 :                :     {
                              13287                 :             38 :         validatorInfo = findFuncByOid(plang->lanvalidator);
 7179                         13288   [ +  +  +  - ]:             38 :         if (validatorInfo != NULL && !validatorInfo->dobj.dump)
 7357                         13289                 :              1 :             validatorInfo = NULL;
                              13290                 :                :     }
                              13291                 :                : 
                              13292                 :                :     /*
                              13293                 :                :      * If the functions are dumpable then emit a complete CREATE LANGUAGE with
                              13294                 :                :      * parameters.  Otherwise, we'll write a parameterless command, which will
                              13295                 :                :      * be interpreted as CREATE EXTENSION.
                              13296                 :                :      */
                              13297         [ +  - ]:             30 :     useParams = (funcInfo != NULL &&
 5879                         13298   [ +  +  +  -  :            129 :                  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
                                              +  - ]
 7357                         13299         [ +  - ]:             30 :                  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
                              13300                 :                : 
 7996                         13301                 :             69 :     defqry = createPQExpBuffer();
                              13302                 :             69 :     delqry = createPQExpBuffer();
                              13303                 :                : 
 5085 bruce@momjian.us        13304                 :             69 :     qlanname = pg_strdup(fmtId(plang->dobj.name));
                              13305                 :                : 
 7996 tgl@sss.pgh.pa.us       13306                 :             69 :     appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                              13307                 :                :                       qlanname);
                              13308                 :                : 
 7357                         13309         [ +  + ]:             69 :     if (useParams)
                              13310                 :                :     {
 5724                         13311                 :             30 :         appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
                              13312         [ -  + ]:             30 :                           plang->lanpltrusted ? "TRUSTED " : "",
                              13313                 :                :                           qlanname);
 7357                         13314                 :             30 :         appendPQExpBuffer(defqry, " HANDLER %s",
 2800                         13315                 :             30 :                           fmtQualifiedDumpable(funcInfo));
 5879                         13316         [ -  + ]:             30 :         if (OidIsValid(plang->laninline))
 2800 tgl@sss.pgh.pa.us       13317                 :UBC           0 :             appendPQExpBuffer(defqry, " INLINE %s",
                              13318                 :              0 :                               fmtQualifiedDumpable(inlineInfo));
 7357 tgl@sss.pgh.pa.us       13319         [ -  + ]:CBC          30 :         if (OidIsValid(plang->lanvalidator))
 2800 tgl@sss.pgh.pa.us       13320                 :UBC           0 :             appendPQExpBuffer(defqry, " VALIDATOR %s",
                              13321                 :              0 :                               fmtQualifiedDumpable(validatorInfo));
                              13322                 :                :     }
                              13323                 :                :     else
                              13324                 :                :     {
                              13325                 :                :         /*
                              13326                 :                :          * If not dumping parameters, then use CREATE OR REPLACE so that the
                              13327                 :                :          * command will not fail if the language is preinstalled in the target
                              13328                 :                :          * database.
                              13329                 :                :          *
                              13330                 :                :          * Modern servers will interpret this as CREATE EXTENSION IF NOT
                              13331                 :                :          * EXISTS; perhaps we should emit that instead?  But it might just add
                              13332                 :                :          * confusion.
                              13333                 :                :          */
 5724 tgl@sss.pgh.pa.us       13334                 :CBC          39 :         appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
                              13335                 :                :                           qlanname);
                              13336                 :                :     }
 4361 heikki.linnakangas@i    13337                 :             69 :     appendPQExpBufferStr(defqry, ";\n");
                              13338                 :                : 
 4031 alvherre@alvh.no-ip.    13339         [ +  + ]:             69 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       13340                 :              2 :         binary_upgrade_extension_member(defqry, &plang->dobj,
                              13341                 :                :                                         "LANGUAGE", qlanname, NULL);
                              13342                 :                : 
 3491 sfrost@snowman.net      13343         [ +  + ]:             69 :     if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13344                 :             31 :         ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    13345                 :             31 :                      ARCHIVE_OPTS(.tag = plang->dobj.name,
                              13346                 :                :                                   .owner = plang->lanowner,
                              13347                 :                :                                   .description = "PROCEDURAL LANGUAGE",
                              13348                 :                :                                   .section = SECTION_PRE_DATA,
                              13349                 :                :                                   .createStmt = defqry->data,
                              13350                 :                :                                   .dropStmt = delqry->data,
                              13351                 :                :                                   ));
                              13352                 :                : 
                              13353                 :                :     /* Dump Proc Lang Comments and Security Labels */
 3491 sfrost@snowman.net      13354         [ -  + ]:             69 :     if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       13355                 :UBC           0 :         dumpComment(fout, "LANGUAGE", qlanname,
                              13356                 :              0 :                     NULL, plang->lanowner,
 3491 sfrost@snowman.net      13357                 :              0 :                     plang->dobj.catId, 0, plang->dobj.dumpId);
                              13358                 :                : 
 3491 sfrost@snowman.net      13359         [ -  + ]:CBC          69 :     if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       13360                 :UBC           0 :         dumpSecLabel(fout, "LANGUAGE", qlanname,
                              13361                 :              0 :                      NULL, plang->lanowner,
 3491 sfrost@snowman.net      13362                 :              0 :                      plang->dobj.catId, 0, plang->dobj.dumpId);
                              13363                 :                : 
 3491 sfrost@snowman.net      13364   [ +  +  +  - ]:CBC          69 :     if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       13365                 :             38 :         dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
                              13366                 :                :                 qlanname, NULL, NULL,
  574                         13367                 :             38 :                 NULL, plang->lanowner, &plang->dacl);
                              13368                 :                : 
 7996                         13369                 :             69 :     free(qlanname);
                              13370                 :                : 
                              13371                 :             69 :     destroyPQExpBuffer(defqry);
                              13372                 :             69 :     destroyPQExpBuffer(delqry);
                              13373                 :                : }
                              13374                 :                : 
                              13375                 :                : /*
                              13376                 :                :  * format_function_arguments: generate function name and argument list
                              13377                 :                :  *
                              13378                 :                :  * This is used when we can rely on pg_get_function_arguments to format
                              13379                 :                :  * the argument list.  Note, however, that pg_get_function_arguments
                              13380                 :                :  * does not special-case zero-argument aggregates.
                              13381                 :                :  */
                              13382                 :                : static char *
 1720 peter@eisentraut.org    13383                 :           4082 : format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
                              13384                 :                : {
                              13385                 :                :     PQExpBufferData fn;
                              13386                 :                : 
 6310 tgl@sss.pgh.pa.us       13387                 :           4082 :     initPQExpBuffer(&fn);
 4361 heikki.linnakangas@i    13388                 :           4082 :     appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
 4437 tgl@sss.pgh.pa.us       13389   [ +  +  +  + ]:           4082 :     if (is_agg && finfo->nargs == 0)
 4361 heikki.linnakangas@i    13390                 :             80 :         appendPQExpBufferStr(&fn, "(*)");
                              13391                 :                :     else
 4437 tgl@sss.pgh.pa.us       13392                 :           4002 :         appendPQExpBuffer(&fn, "(%s)", funcargs);
 6310                         13393                 :           4082 :     return fn.data;
                              13394                 :                : }
                              13395                 :                : 
                              13396                 :                : /*
                              13397                 :                :  * format_function_signature: generate function name and argument list
                              13398                 :                :  *
                              13399                 :                :  * Only a minimal list of input argument types is generated; this is
                              13400                 :                :  * sufficient to reference the function, but not to define it.
                              13401                 :                :  *
                              13402                 :                :  * If honor_quotes is false then the function name is never quoted.
                              13403                 :                :  * This is appropriate for use in TOC tags, but not in SQL commands.
                              13404                 :                :  */
                              13405                 :                : static char *
 1720 peter@eisentraut.org    13406                 :           2149 : format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
                              13407                 :                : {
                              13408                 :                :     PQExpBufferData fn;
                              13409                 :                :     int         j;
                              13410                 :                : 
 7514 tgl@sss.pgh.pa.us       13411                 :           2149 :     initPQExpBuffer(&fn);
                              13412         [ +  + ]:           2149 :     if (honor_quotes)
                              13413                 :            393 :         appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
                              13414                 :                :     else
                              13415                 :           1756 :         appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
                              13416         [ +  + ]:           3945 :     for (j = 0; j < finfo->nargs; j++)
                              13417                 :                :     {
 4361 heikki.linnakangas@i    13418         [ +  + ]:           1796 :         if (j > 0)
                              13419                 :            422 :             appendPQExpBufferStr(&fn, ", ");
                              13420                 :                : 
 1510 tgl@sss.pgh.pa.us       13421                 :           1796 :         appendPQExpBufferStr(&fn,
                              13422                 :           1796 :                              getFormattedTypeName(fout, finfo->argtypes[j],
                              13423                 :                :                                                   zeroIsError));
                              13424                 :                :     }
 4361 heikki.linnakangas@i    13425                 :           2149 :     appendPQExpBufferChar(&fn, ')');
 7514 tgl@sss.pgh.pa.us       13426                 :           2149 :     return fn.data;
                              13427                 :                : }
                              13428                 :                : 
                              13429                 :                : 
                              13430                 :                : /*
                              13431                 :                :  * dumpFunc:
                              13432                 :                :  *    dump out one function
                              13433                 :                :  */
                              13434                 :                : static void
 1720 peter@eisentraut.org    13435                 :           1818 : dumpFunc(Archive *fout, const FuncInfo *finfo)
                              13436                 :                : {
 3575 tgl@sss.pgh.pa.us       13437                 :           1818 :     DumpOptions *dopt = fout->dopt;
                              13438                 :                :     PQExpBuffer query;
                              13439                 :                :     PQExpBuffer q;
                              13440                 :                :     PQExpBuffer delqry;
                              13441                 :                :     PQExpBuffer asPart;
                              13442                 :                :     PGresult   *res;
                              13443                 :                :     char       *funcsig;        /* identity signature */
 3050                         13444                 :           1818 :     char       *funcfullsig = NULL; /* full signature */
                              13445                 :                :     char       *funcsig_tag;
                              13446                 :                :     char       *qual_funcsig;
                              13447                 :                :     char       *proretset;
                              13448                 :                :     char       *prosrc;
                              13449                 :                :     char       *probin;
                              13450                 :                :     char       *prosqlbody;
                              13451                 :                :     char       *funcargs;
                              13452                 :                :     char       *funciargs;
                              13453                 :                :     char       *funcresult;
                              13454                 :                :     char       *protrftypes;
                              13455                 :                :     char       *prokind;
                              13456                 :                :     char       *provolatile;
                              13457                 :                :     char       *proisstrict;
                              13458                 :                :     char       *prosecdef;
                              13459                 :                :     char       *proleakproof;
                              13460                 :                :     char       *proconfig;
                              13461                 :                :     char       *procost;
                              13462                 :                :     char       *prorows;
                              13463                 :                :     char       *prosupport;
                              13464                 :                :     char       *proparallel;
                              13465                 :                :     char       *lanname;
 6629                         13466                 :           1818 :     char      **configitems = NULL;
                              13467                 :           1818 :     int         nconfigitems = 0;
                              13468                 :                :     const char *keyword;
                              13469                 :                : 
                              13470                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    13471         [ +  + ]:           1818 :     if (!dopt->dumpSchema)
 7378 tgl@sss.pgh.pa.us       13472                 :             62 :         return;
                              13473                 :                : 
 7996                         13474                 :           1756 :     query = createPQExpBuffer();
                              13475                 :           1756 :     q = createPQExpBuffer();
                              13476                 :           1756 :     delqry = createPQExpBuffer();
                              13477                 :           1756 :     asPart = createPQExpBuffer();
                              13478                 :                : 
 1421                         13479         [ +  + ]:           1756 :     if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
                              13480                 :                :     {
                              13481                 :                :         /* Set up query for function-specific details */
 1838 drowley@postgresql.o    13482                 :             66 :         appendPQExpBufferStr(query,
                              13483                 :                :                              "PREPARE dumpFunc(pg_catalog.oid) AS\n");
                              13484                 :                : 
                              13485                 :             66 :         appendPQExpBufferStr(query,
                              13486                 :                :                              "SELECT\n"
                              13487                 :                :                              "proretset,\n"
                              13488                 :                :                              "prosrc,\n"
                              13489                 :                :                              "probin,\n"
                              13490                 :                :                              "provolatile,\n"
                              13491                 :                :                              "proisstrict,\n"
                              13492                 :                :                              "prosecdef,\n"
                              13493                 :                :                              "lanname,\n"
                              13494                 :                :                              "proconfig,\n"
                              13495                 :                :                              "procost,\n"
                              13496                 :                :                              "prorows,\n"
                              13497                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              13498                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
                              13499                 :                :                              "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
                              13500                 :                :                              "proleakproof,\n");
                              13501                 :                : 
 1421 tgl@sss.pgh.pa.us       13502         [ +  - ]:             66 :         if (fout->remoteVersion >= 90500)
                              13503                 :             66 :             appendPQExpBufferStr(query,
                              13504                 :                :                                  "array_to_string(protrftypes, ' ') AS protrftypes,\n");
                              13505                 :                :         else
 1408 tgl@sss.pgh.pa.us       13506                 :UBC           0 :             appendPQExpBufferStr(query,
                              13507                 :                :                                  "NULL AS protrftypes,\n");
                              13508                 :                : 
 1421 tgl@sss.pgh.pa.us       13509         [ +  - ]:CBC          66 :         if (fout->remoteVersion >= 90600)
                              13510                 :             66 :             appendPQExpBufferStr(query,
                              13511                 :                :                                  "proparallel,\n");
                              13512                 :                :         else
 1421 tgl@sss.pgh.pa.us       13513                 :UBC           0 :             appendPQExpBufferStr(query,
                              13514                 :                :                                  "'u' AS proparallel,\n");
                              13515                 :                : 
 1421 tgl@sss.pgh.pa.us       13516         [ +  - ]:CBC          66 :         if (fout->remoteVersion >= 110000)
                              13517                 :             66 :             appendPQExpBufferStr(query,
                              13518                 :                :                                  "prokind,\n");
                              13519                 :                :         else
 1421 tgl@sss.pgh.pa.us       13520                 :UBC           0 :             appendPQExpBufferStr(query,
                              13521                 :                :                                  "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
                              13522                 :                : 
 1421 tgl@sss.pgh.pa.us       13523         [ +  - ]:CBC          66 :         if (fout->remoteVersion >= 120000)
                              13524                 :             66 :             appendPQExpBufferStr(query,
                              13525                 :                :                                  "prosupport,\n");
                              13526                 :                :         else
 1421 tgl@sss.pgh.pa.us       13527                 :UBC           0 :             appendPQExpBufferStr(query,
                              13528                 :                :                                  "'-' AS prosupport,\n");
                              13529                 :                : 
 1421 tgl@sss.pgh.pa.us       13530         [ +  - ]:CBC          66 :         if (fout->remoteVersion >= 140000)
                              13531                 :             66 :             appendPQExpBufferStr(query,
                              13532                 :                :                                  "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
                              13533                 :                :         else
 1421 tgl@sss.pgh.pa.us       13534                 :UBC           0 :             appendPQExpBufferStr(query,
                              13535                 :                :                                  "NULL AS prosqlbody\n");
                              13536                 :                : 
 1664 peter@eisentraut.org    13537                 :CBC          66 :         appendPQExpBufferStr(query,
                              13538                 :                :                              "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
                              13539                 :                :                              "WHERE p.oid = $1 "
                              13540                 :                :                              "AND l.oid = p.prolang");
                              13541                 :                : 
 1421 tgl@sss.pgh.pa.us       13542                 :             66 :         ExecuteSqlStatement(fout, query->data);
                              13543                 :                : 
                              13544                 :             66 :         fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
                              13545                 :                :     }
                              13546                 :                : 
                              13547                 :           1756 :     printfPQExpBuffer(query,
                              13548                 :                :                       "EXECUTE dumpFunc('%u')",
 1930 peter@eisentraut.org    13549                 :           1756 :                       finfo->dobj.catId.oid);
                              13550                 :                : 
 5002 rhaas@postgresql.org    13551                 :           1756 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13552                 :                : 
 8571 tgl@sss.pgh.pa.us       13553                 :           1756 :     proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
 1664 peter@eisentraut.org    13554         [ +  + ]:           1756 :     if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
                              13555                 :                :     {
                              13556                 :           1708 :         prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
                              13557                 :           1708 :         probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
                              13558                 :           1708 :         prosqlbody = NULL;
                              13559                 :                :     }
                              13560                 :                :     else
                              13561                 :                :     {
                              13562                 :             48 :         prosrc = NULL;
                              13563                 :             48 :         probin = NULL;
                              13564                 :             48 :         prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
                              13565                 :                :     }
 1413 tgl@sss.pgh.pa.us       13566                 :           1756 :     funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              13567                 :           1756 :     funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              13568                 :           1756 :     funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
 1408                         13569                 :           1756 :     protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
 2796 peter_e@gmx.net         13570                 :           1756 :     prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
 8571 tgl@sss.pgh.pa.us       13571                 :           1756 :     provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
                              13572                 :           1756 :     proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
 8563 peter_e@gmx.net         13573                 :           1756 :     prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
 5005 rhaas@postgresql.org    13574                 :           1756 :     proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
 6629 tgl@sss.pgh.pa.us       13575                 :           1756 :     proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
 6853                         13576                 :           1756 :     procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
                              13577                 :           1756 :     prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
 2452                         13578                 :           1756 :     prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
 1930 peter@eisentraut.org    13579                 :           1756 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
 8571 tgl@sss.pgh.pa.us       13580                 :           1756 :     lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
                              13581                 :                : 
                              13582                 :                :     /*
                              13583                 :                :      * See backend/commands/functioncmds.c for details of how the 'AS' clause
                              13584                 :                :      * is used.
                              13585                 :                :      */
 1664 peter@eisentraut.org    13586         [ +  + ]:           1756 :     if (prosqlbody)
                              13587                 :                :     {
                              13588                 :             48 :         appendPQExpBufferStr(asPart, prosqlbody);
                              13589                 :                :     }
 1411 tgl@sss.pgh.pa.us       13590         [ +  + ]:           1708 :     else if (probin[0] != '\0')
                              13591                 :                :     {
 4361 heikki.linnakangas@i    13592                 :            137 :         appendPQExpBufferStr(asPart, "AS ");
 7092 tgl@sss.pgh.pa.us       13593                 :            137 :         appendStringLiteralAH(asPart, probin, fout);
 1411                         13594         [ +  - ]:            137 :         if (prosrc[0] != '\0')
                              13595                 :                :         {
 4361 heikki.linnakangas@i    13596                 :            137 :             appendPQExpBufferStr(asPart, ", ");
                              13597                 :                : 
                              13598                 :                :             /*
                              13599                 :                :              * where we have bin, use dollar quoting if allowed and src
                              13600                 :                :              * contains quote or backslash; else use regular quoting.
                              13601                 :                :              */
 4031 alvherre@alvh.no-ip.    13602         [ +  - ]:            137 :             if (dopt->disable_dollar_quoting ||
 3050 tgl@sss.pgh.pa.us       13603   [ +  -  +  - ]:            137 :                 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
 7092                         13604                 :            137 :                 appendStringLiteralAH(asPart, prosrc, fout);
                              13605                 :                :             else
 7092 tgl@sss.pgh.pa.us       13606                 :UBC           0 :                 appendStringLiteralDQ(asPart, prosrc, NULL);
                              13607                 :                :         }
                              13608                 :                :     }
                              13609                 :                :     else
                              13610                 :                :     {
 1411 tgl@sss.pgh.pa.us       13611                 :CBC        1571 :         appendPQExpBufferStr(asPart, "AS ");
                              13612                 :                :         /* with no bin, dollar quote src unconditionally if allowed */
                              13613         [ -  + ]:           1571 :         if (dopt->disable_dollar_quoting)
 1411 tgl@sss.pgh.pa.us       13614                 :UBC           0 :             appendStringLiteralAH(asPart, prosrc, fout);
                              13615                 :                :         else
 1411 tgl@sss.pgh.pa.us       13616                 :CBC        1571 :             appendStringLiteralDQ(asPart, prosrc, NULL);
                              13617                 :                :     }
                              13618                 :                : 
 1408                         13619         [ +  + ]:           1756 :     if (*proconfig)
                              13620                 :                :     {
 6629                         13621         [ -  + ]:             15 :         if (!parsePGArray(proconfig, &configitems, &nconfigitems))
 1298 tgl@sss.pgh.pa.us       13622                 :UBC           0 :             pg_fatal("could not parse %s array", "proconfig");
                              13623                 :                :     }
                              13624                 :                :     else
                              13625                 :                :     {
 1803 michael@paquier.xyz     13626                 :CBC        1741 :         configitems = NULL;
                              13627                 :           1741 :         nconfigitems = 0;
                              13628                 :                :     }
                              13629                 :                : 
 1413 tgl@sss.pgh.pa.us       13630                 :           1756 :     funcfullsig = format_function_arguments(finfo, funcargs, false);
                              13631                 :           1756 :     funcsig = format_function_arguments(finfo, funciargs, false);
                              13632                 :                : 
 5012 rhaas@postgresql.org    13633                 :           1756 :     funcsig_tag = format_function_signature(fout, finfo, false);
                              13634                 :                : 
 1464 tgl@sss.pgh.pa.us       13635                 :           1756 :     qual_funcsig = psprintf("%s.%s",
                              13636                 :           1756 :                             fmtId(finfo->dobj.namespace->dobj.name),
                              13637                 :                :                             funcsig);
                              13638                 :                : 
 2796 peter_e@gmx.net         13639         [ +  + ]:           1756 :     if (prokind[0] == PROKIND_PROCEDURE)
                              13640                 :             92 :         keyword = "PROCEDURE";
                              13641                 :                :     else
                              13642                 :           1664 :         keyword = "FUNCTION"; /* works for window functions too */
                              13643                 :                : 
 1464 tgl@sss.pgh.pa.us       13644                 :           1756 :     appendPQExpBuffer(delqry, "DROP %s %s;\n",
                              13645                 :                :                       keyword, qual_funcsig);
                              13646                 :                : 
 2800                         13647         [ +  - ]:           3512 :     appendPQExpBuffer(q, "CREATE %s %s.%s",
                              13648                 :                :                       keyword,
                              13649                 :           1756 :                       fmtId(finfo->dobj.namespace->dobj.name),
                              13650                 :                :                       funcfullsig ? funcfullsig :
                              13651                 :                :                       funcsig);
                              13652                 :                : 
 2796 peter_e@gmx.net         13653         [ +  + ]:           1756 :     if (prokind[0] == PROKIND_PROCEDURE)
                              13654                 :                :          /* no result type to output */ ;
 2888                         13655         [ +  - ]:           1664 :     else if (funcresult)
                              13656                 :           1664 :         appendPQExpBuffer(q, " RETURNS %s", funcresult);
                              13657                 :                :     else
 2888 peter_e@gmx.net         13658                 :UBC           0 :         appendPQExpBuffer(q, " RETURNS %s%s",
 6310 tgl@sss.pgh.pa.us       13659         [ #  # ]:              0 :                           (proretset[0] == 't') ? "SETOF " : "",
 1510                         13660                 :              0 :                           getFormattedTypeName(fout, finfo->prorettype,
                              13661                 :                :                                                zeroIsError));
                              13662                 :                : 
 6327 heikki.linnakangas@i    13663                 :CBC        1756 :     appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));
                              13664                 :                : 
 1408 tgl@sss.pgh.pa.us       13665         [ -  + ]:           1756 :     if (*protrftypes)
                              13666                 :                :     {
  320 dgustafsson@postgres    13667                 :UBC           0 :         Oid        *typeids = pg_malloc(FUNC_MAX_ARGS * sizeof(Oid));
                              13668                 :                :         int         i;
                              13669                 :                : 
 3837 peter_e@gmx.net         13670                 :              0 :         appendPQExpBufferStr(q, " TRANSFORM ");
                              13671                 :              0 :         parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
                              13672         [ #  # ]:              0 :         for (i = 0; typeids[i]; i++)
                              13673                 :                :         {
                              13674         [ #  # ]:              0 :             if (i != 0)
                              13675                 :              0 :                 appendPQExpBufferStr(q, ", ");
                              13676                 :              0 :             appendPQExpBuffer(q, "FOR TYPE %s",
 3050 tgl@sss.pgh.pa.us       13677                 :              0 :                               getFormattedTypeName(fout, typeids[i], zeroAsNone));
                              13678                 :                :         }
                              13679                 :                : 
  320 dgustafsson@postgres    13680                 :              0 :         free(typeids);
                              13681                 :                :     }
                              13682                 :                : 
 2796 peter_e@gmx.net         13683         [ +  + ]:CBC        1756 :     if (prokind[0] == PROKIND_WINDOW)
 4361 heikki.linnakangas@i    13684                 :              5 :         appendPQExpBufferStr(q, " WINDOW");
                              13685                 :                : 
 8564 peter_e@gmx.net         13686         [ +  + ]:           1756 :     if (provolatile[0] != PROVOLATILE_VOLATILE)
                              13687                 :                :     {
 8571 tgl@sss.pgh.pa.us       13688         [ +  + ]:            351 :         if (provolatile[0] == PROVOLATILE_IMMUTABLE)
 4361 heikki.linnakangas@i    13689                 :            330 :             appendPQExpBufferStr(q, " IMMUTABLE");
 8571 tgl@sss.pgh.pa.us       13690         [ +  - ]:             21 :         else if (provolatile[0] == PROVOLATILE_STABLE)
 4361 heikki.linnakangas@i    13691                 :             21 :             appendPQExpBufferStr(q, " STABLE");
 8571 tgl@sss.pgh.pa.us       13692         [ #  # ]:UBC           0 :         else if (provolatile[0] != PROVOLATILE_VOLATILE)
 1298                         13693                 :              0 :             pg_fatal("unrecognized provolatile value for function \"%s\"",
                              13694                 :                :                      finfo->dobj.name);
                              13695                 :                :     }
                              13696                 :                : 
 8564 peter_e@gmx.net         13697         [ +  + ]:CBC        1756 :     if (proisstrict[0] == 't')
 4361 heikki.linnakangas@i    13698                 :            353 :         appendPQExpBufferStr(q, " STRICT");
                              13699                 :                : 
 8563 peter_e@gmx.net         13700         [ -  + ]:           1756 :     if (prosecdef[0] == 't')
 4361 heikki.linnakangas@i    13701                 :UBC           0 :         appendPQExpBufferStr(q, " SECURITY DEFINER");
                              13702                 :                : 
 5005 rhaas@postgresql.org    13703         [ +  + ]:CBC        1756 :     if (proleakproof[0] == 't')
 4361 heikki.linnakangas@i    13704                 :             10 :         appendPQExpBufferStr(q, " LEAKPROOF");
                              13705                 :                : 
                              13706                 :                :     /*
                              13707                 :                :      * COST and ROWS are emitted only if present and not default, so as not to
                              13708                 :                :      * break backwards-compatibility of the dump without need.  Keep this code
                              13709                 :                :      * in sync with the defaults in functioncmds.c.
                              13710                 :                :      */
 6853 tgl@sss.pgh.pa.us       13711         [ +  - ]:           1756 :     if (strcmp(procost, "0") != 0)
                              13712                 :                :     {
                              13713   [ +  +  +  + ]:           1756 :         if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
                              13714                 :                :         {
                              13715                 :                :             /* default cost is 1 */
                              13716         [ -  + ]:            366 :             if (strcmp(procost, "1") != 0)
 6853 tgl@sss.pgh.pa.us       13717                 :UBC           0 :                 appendPQExpBuffer(q, " COST %s", procost);
                              13718                 :                :         }
                              13719                 :                :         else
                              13720                 :                :         {
                              13721                 :                :             /* default cost is 100 */
 6853 tgl@sss.pgh.pa.us       13722         [ +  + ]:CBC        1390 :             if (strcmp(procost, "100") != 0)
                              13723                 :              6 :                 appendPQExpBuffer(q, " COST %s", procost);
                              13724                 :                :         }
                              13725                 :                :     }
                              13726         [ +  + ]:           1756 :     if (proretset[0] == 't' &&
                              13727   [ +  -  -  + ]:            187 :         strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
 6853 tgl@sss.pgh.pa.us       13728                 :UBC           0 :         appendPQExpBuffer(q, " ROWS %s", prorows);
                              13729                 :                : 
 2452 tgl@sss.pgh.pa.us       13730         [ +  + ]:CBC        1756 :     if (strcmp(prosupport, "-") != 0)
                              13731                 :                :     {
                              13732                 :                :         /* We rely on regprocout to provide quoting and qualification */
                              13733                 :             42 :         appendPQExpBuffer(q, " SUPPORT %s", prosupport);
                              13734                 :                :     }
                              13735                 :                : 
 1930 peter@eisentraut.org    13736         [ +  + ]:           1756 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              13737                 :                :     {
 3694 rhaas@postgresql.org    13738         [ +  + ]:            116 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              13739                 :            111 :             appendPQExpBufferStr(q, " PARALLEL SAFE");
                              13740         [ +  - ]:              5 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              13741                 :              5 :             appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
 3694 rhaas@postgresql.org    13742         [ #  # ]:UBC           0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
 1298 tgl@sss.pgh.pa.us       13743                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              13744                 :                :                      finfo->dobj.name);
                              13745                 :                :     }
                              13746                 :                : 
 1160 drowley@postgresql.o    13747         [ +  + ]:CBC        1791 :     for (int i = 0; i < nconfigitems; i++)
                              13748                 :                :     {
                              13749                 :                :         /* we feel free to scribble on configitems[] here */
 6629 tgl@sss.pgh.pa.us       13750                 :             35 :         char       *configitem = configitems[i];
                              13751                 :                :         char       *pos;
                              13752                 :                : 
                              13753                 :             35 :         pos = strchr(configitem, '=');
                              13754         [ -  + ]:             35 :         if (pos == NULL)
 6629 tgl@sss.pgh.pa.us       13755                 :UBC           0 :             continue;
 6629 tgl@sss.pgh.pa.us       13756                 :CBC          35 :         *pos++ = '\0';
                              13757                 :             35 :         appendPQExpBuffer(q, "\n    SET %s TO ", fmtId(configitem));
                              13758                 :                : 
                              13759                 :                :         /*
                              13760                 :                :          * Variables that are marked GUC_LIST_QUOTE were already fully quoted
                              13761                 :                :          * by flatten_set_variable_args() before they were put into the
                              13762                 :                :          * proconfig array.  However, because the quoting rules used there
                              13763                 :                :          * aren't exactly like SQL's, we have to break the list value apart
                              13764                 :                :          * and then quote the elements as string literals.  (The elements may
                              13765                 :                :          * be double-quoted as-is, but we can't just feed them to the SQL
                              13766                 :                :          * parser; it would do the wrong thing with elements that are
                              13767                 :                :          * zero-length or longer than NAMEDATALEN.)
                              13768                 :                :          *
                              13769                 :                :          * Variables that are not so marked should just be emitted as simple
                              13770                 :                :          * string literals.  If the variable is not known to
                              13771                 :                :          * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
                              13772                 :                :          * to use GUC_LIST_QUOTE for extension variables.
                              13773                 :                :          */
 2777                         13774         [ +  + ]:             35 :         if (variable_is_guc_list_quote(configitem))
                              13775                 :                :         {
                              13776                 :                :             char      **namelist;
                              13777                 :                :             char      **nameptr;
                              13778                 :                : 
                              13779                 :                :             /* Parse string into list of identifiers */
                              13780                 :                :             /* this shouldn't fail really */
 2645                         13781         [ +  - ]:             10 :             if (SplitGUCList(pos, ',', &namelist))
                              13782                 :                :             {
                              13783         [ +  + ]:             35 :                 for (nameptr = namelist; *nameptr; nameptr++)
                              13784                 :                :                 {
                              13785         [ +  + ]:             25 :                     if (nameptr != namelist)
                              13786                 :             15 :                         appendPQExpBufferStr(q, ", ");
                              13787                 :             25 :                     appendStringLiteralAH(q, *nameptr, fout);
                              13788                 :                :                 }
                              13789                 :                :             }
                              13790                 :             10 :             pg_free(namelist);
                              13791                 :                :         }
                              13792                 :                :         else
 6629                         13793                 :             25 :             appendStringLiteralAH(q, pos, fout);
                              13794                 :                :     }
                              13795                 :                : 
 6327 heikki.linnakangas@i    13796                 :           1756 :     appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
                              13797                 :                : 
 2056 alvherre@alvh.no-ip.    13798                 :           1756 :     append_depends_on_extension(fout, q, &finfo->dobj,
                              13799                 :                :                                 "pg_catalog.pg_proc", keyword,
                              13800                 :                :                                 qual_funcsig);
                              13801                 :                : 
 4031                         13802         [ +  + ]:           1756 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       13803                 :            293 :         binary_upgrade_extension_member(q, &finfo->dobj,
                              13804                 :                :                                         keyword, funcsig,
                              13805                 :            293 :                                         finfo->dobj.namespace->dobj.name);
                              13806                 :                : 
 3491 sfrost@snowman.net      13807         [ +  + ]:           1756 :     if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13808                 :           1660 :         ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    13809         [ +  + ]:           1660 :                      ARCHIVE_OPTS(.tag = funcsig_tag,
                              13810                 :                :                                   .namespace = finfo->dobj.namespace->dobj.name,
                              13811                 :                :                                   .owner = finfo->rolname,
                              13812                 :                :                                   .description = keyword,
                              13813                 :                :                                   .section = finfo->postponed_def ?
                              13814                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              13815                 :                :                                   .createStmt = q->data,
                              13816                 :                :                                   .dropStmt = delqry->data));
                              13817                 :                : 
                              13818                 :                :     /* Dump Function Comments and Security Labels */
 3491 sfrost@snowman.net      13819         [ +  + ]:           1756 :     if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       13820                 :              9 :         dumpComment(fout, keyword, funcsig,
 3491 sfrost@snowman.net      13821                 :              9 :                     finfo->dobj.namespace->dobj.name, finfo->rolname,
                              13822                 :              9 :                     finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              13823                 :                : 
                              13824         [ -  + ]:           1756 :     if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       13825                 :UBC           0 :         dumpSecLabel(fout, keyword, funcsig,
 3491 sfrost@snowman.net      13826                 :              0 :                      finfo->dobj.namespace->dobj.name, finfo->rolname,
                              13827                 :              0 :                      finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              13828                 :                : 
 3491 sfrost@snowman.net      13829         [ +  + ]:CBC        1756 :     if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       13830                 :            100 :         dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
                              13831                 :                :                 funcsig, NULL,
 3491 sfrost@snowman.net      13832                 :            100 :                 finfo->dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       13833                 :            100 :                 NULL, finfo->rolname, &finfo->dacl);
                              13834                 :                : 
 8571                         13835                 :           1756 :     PQclear(res);
                              13836                 :                : 
                              13837                 :           1756 :     destroyPQExpBuffer(query);
 8851                         13838                 :           1756 :     destroyPQExpBuffer(q);
                              13839                 :           1756 :     destroyPQExpBuffer(delqry);
                              13840                 :           1756 :     destroyPQExpBuffer(asPart);
 8562 peter_e@gmx.net         13841                 :           1756 :     free(funcsig);
 1229 peter@eisentraut.org    13842                 :           1756 :     free(funcfullsig);
 8516 bruce@momjian.us        13843                 :           1756 :     free(funcsig_tag);
 1464 tgl@sss.pgh.pa.us       13844                 :           1756 :     free(qual_funcsig);
 1229 peter@eisentraut.org    13845                 :           1756 :     free(configitems);
                              13846                 :                : }
                              13847                 :                : 
                              13848                 :                : 
                              13849                 :                : /*
                              13850                 :                :  * Dump a user-defined cast
                              13851                 :                :  */
                              13852                 :                : static void
 1720                         13853                 :             67 : dumpCast(Archive *fout, const CastInfo *cast)
                              13854                 :                : {
 3575 tgl@sss.pgh.pa.us       13855                 :             67 :     DumpOptions *dopt = fout->dopt;
                              13856                 :                :     PQExpBuffer defqry;
                              13857                 :                :     PQExpBuffer delqry;
                              13858                 :                :     PQExpBuffer labelq;
                              13859                 :                :     PQExpBuffer castargs;
 7996                         13860                 :             67 :     FuncInfo   *funcInfo = NULL;
                              13861                 :                :     const char *sourceType;
                              13862                 :                :     const char *targetType;
                              13863                 :                : 
                              13864                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    13865         [ +  + ]:             67 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       13866                 :              6 :         return;
                              13867                 :                : 
                              13868                 :                :     /* Cannot dump if we don't have the cast function's info */
                              13869         [ +  + ]:             61 :     if (OidIsValid(cast->castfunc))
                              13870                 :                :     {
                              13871                 :             36 :         funcInfo = findFuncByOid(cast->castfunc);
                              13872         [ -  + ]:             36 :         if (funcInfo == NULL)
 1298 tgl@sss.pgh.pa.us       13873                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13874                 :                :                      cast->castfunc);
                              13875                 :                :     }
                              13876                 :                : 
 7996 tgl@sss.pgh.pa.us       13877                 :CBC          61 :     defqry = createPQExpBuffer();
                              13878                 :             61 :     delqry = createPQExpBuffer();
 5374                         13879                 :             61 :     labelq = createPQExpBuffer();
 2800                         13880                 :             61 :     castargs = createPQExpBuffer();
                              13881                 :                : 
 3770 heikki.linnakangas@i    13882                 :             61 :     sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
                              13883                 :             61 :     targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
 7996 tgl@sss.pgh.pa.us       13884                 :             61 :     appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
                              13885                 :                :                       sourceType, targetType);
                              13886                 :                : 
                              13887                 :             61 :     appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
                              13888                 :                :                       sourceType, targetType);
                              13889                 :                : 
 5982 bruce@momjian.us        13890   [ +  -  +  - ]:             61 :     switch (cast->castmethod)
                              13891                 :                :     {
 6205 heikki.linnakangas@i    13892                 :             25 :         case COERCION_METHOD_BINARY:
 4361                         13893                 :             25 :             appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
 6205                         13894                 :             25 :             break;
 6205 heikki.linnakangas@i    13895                 :UBC           0 :         case COERCION_METHOD_INOUT:
 4361                         13896                 :              0 :             appendPQExpBufferStr(defqry, "WITH INOUT");
 6205                         13897                 :              0 :             break;
 6205 heikki.linnakangas@i    13898                 :CBC          36 :         case COERCION_METHOD_FUNCTION:
 4973 peter_e@gmx.net         13899         [ +  - ]:             36 :             if (funcInfo)
                              13900                 :                :             {
 4887 bruce@momjian.us        13901                 :             36 :                 char       *fsig = format_function_signature(fout, funcInfo, true);
                              13902                 :                : 
                              13903                 :                :                 /*
                              13904                 :                :                  * Always qualify the function name (format_function_signature
                              13905                 :                :                  * won't qualify it).
                              13906                 :                :                  */
 4973 peter_e@gmx.net         13907                 :             36 :                 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
 3050 tgl@sss.pgh.pa.us       13908                 :             36 :                                   fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
 4973 peter_e@gmx.net         13909                 :             36 :                 free(fsig);
                              13910                 :                :             }
                              13911                 :                :             else
 2401 peter@eisentraut.org    13912                 :UBC           0 :                 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
 6205 heikki.linnakangas@i    13913                 :CBC          36 :             break;
 6205 heikki.linnakangas@i    13914                 :UBC           0 :         default:
 2401 peter@eisentraut.org    13915                 :              0 :             pg_log_warning("bogus value in pg_cast.castmethod field");
                              13916                 :                :     }
                              13917                 :                : 
 7996 tgl@sss.pgh.pa.us       13918         [ +  + ]:CBC          61 :     if (cast->castcontext == 'a')
 4361 heikki.linnakangas@i    13919                 :             31 :         appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
 7996 tgl@sss.pgh.pa.us       13920         [ +  + ]:             30 :     else if (cast->castcontext == 'i')
 4361 heikki.linnakangas@i    13921                 :             10 :         appendPQExpBufferStr(defqry, " AS IMPLICIT");
                              13922                 :             61 :     appendPQExpBufferStr(defqry, ";\n");
                              13923                 :                : 
 5374 tgl@sss.pgh.pa.us       13924                 :             61 :     appendPQExpBuffer(labelq, "CAST (%s AS %s)",
                              13925                 :                :                       sourceType, targetType);
                              13926                 :                : 
 2800                         13927                 :             61 :     appendPQExpBuffer(castargs, "(%s AS %s)",
                              13928                 :                :                       sourceType, targetType);
                              13929                 :                : 
 4031 alvherre@alvh.no-ip.    13930         [ +  + ]:             61 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       13931                 :              7 :         binary_upgrade_extension_member(defqry, &cast->dobj,
                              13932                 :              7 :                                         "CAST", castargs->data, NULL);
                              13933                 :                : 
 3491 sfrost@snowman.net      13934         [ +  - ]:             61 :     if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13935                 :             61 :         ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    13936                 :             61 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              13937                 :                :                                   .description = "CAST",
                              13938                 :                :                                   .section = SECTION_PRE_DATA,
                              13939                 :                :                                   .createStmt = defqry->data,
                              13940                 :                :                                   .dropStmt = delqry->data));
                              13941                 :                : 
                              13942                 :                :     /* Dump Cast Comments */
 3491 sfrost@snowman.net      13943         [ -  + ]:             61 :     if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       13944                 :UBC           0 :         dumpComment(fout, "CAST", castargs->data,
                              13945                 :                :                     NULL, "",
 3491 sfrost@snowman.net      13946                 :              0 :                     cast->dobj.catId, 0, cast->dobj.dumpId);
                              13947                 :                : 
 8502 peter_e@gmx.net         13948                 :CBC          61 :     destroyPQExpBuffer(defqry);
                              13949                 :             61 :     destroyPQExpBuffer(delqry);
 5374 tgl@sss.pgh.pa.us       13950                 :             61 :     destroyPQExpBuffer(labelq);
 2800                         13951                 :             61 :     destroyPQExpBuffer(castargs);
                              13952                 :                : }
                              13953                 :                : 
                              13954                 :                : /*
                              13955                 :                :  * Dump a transform
                              13956                 :                :  */
                              13957                 :                : static void
 1720 peter@eisentraut.org    13958                 :             42 : dumpTransform(Archive *fout, const TransformInfo *transform)
                              13959                 :                : {
 3575 tgl@sss.pgh.pa.us       13960                 :             42 :     DumpOptions *dopt = fout->dopt;
                              13961                 :                :     PQExpBuffer defqry;
                              13962                 :                :     PQExpBuffer delqry;
                              13963                 :                :     PQExpBuffer labelq;
                              13964                 :                :     PQExpBuffer transformargs;
 3837 peter_e@gmx.net         13965                 :             42 :     FuncInfo   *fromsqlFuncInfo = NULL;
                              13966                 :             42 :     FuncInfo   *tosqlFuncInfo = NULL;
                              13967                 :                :     char       *lanname;
                              13968                 :                :     const char *transformType;
                              13969                 :                : 
                              13970                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    13971         [ +  + ]:             42 :     if (!dopt->dumpSchema)
 3837 peter_e@gmx.net         13972                 :              6 :         return;
                              13973                 :                : 
                              13974                 :                :     /* Cannot dump if we don't have the transform functions' info */
                              13975         [ +  - ]:             36 :     if (OidIsValid(transform->trffromsql))
                              13976                 :                :     {
                              13977                 :             36 :         fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
                              13978         [ -  + ]:             36 :         if (fromsqlFuncInfo == NULL)
 1298 tgl@sss.pgh.pa.us       13979                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13980                 :                :                      transform->trffromsql);
                              13981                 :                :     }
 3837 peter_e@gmx.net         13982         [ +  - ]:CBC          36 :     if (OidIsValid(transform->trftosql))
                              13983                 :                :     {
                              13984                 :             36 :         tosqlFuncInfo = findFuncByOid(transform->trftosql);
                              13985         [ -  + ]:             36 :         if (tosqlFuncInfo == NULL)
 1298 tgl@sss.pgh.pa.us       13986                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13987                 :                :                      transform->trftosql);
                              13988                 :                :     }
                              13989                 :                : 
 3837 peter_e@gmx.net         13990                 :CBC          36 :     defqry = createPQExpBuffer();
                              13991                 :             36 :     delqry = createPQExpBuffer();
                              13992                 :             36 :     labelq = createPQExpBuffer();
 2800 tgl@sss.pgh.pa.us       13993                 :             36 :     transformargs = createPQExpBuffer();
                              13994                 :                : 
 3837 peter_e@gmx.net         13995                 :             36 :     lanname = get_language_name(fout, transform->trflang);
 3770 heikki.linnakangas@i    13996                 :             36 :     transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
                              13997                 :                : 
 3837 peter_e@gmx.net         13998                 :             36 :     appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
                              13999                 :                :                       transformType, lanname);
                              14000                 :                : 
                              14001                 :             36 :     appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
                              14002                 :                :                       transformType, lanname);
                              14003                 :                : 
                              14004   [ -  +  -  - ]:             36 :     if (!transform->trffromsql && !transform->trftosql)
 2401 peter@eisentraut.org    14005                 :UBC           0 :         pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
                              14006                 :                : 
 3837 peter_e@gmx.net         14007         [ +  - ]:CBC          36 :     if (transform->trffromsql)
                              14008                 :                :     {
                              14009         [ +  - ]:             36 :         if (fromsqlFuncInfo)
                              14010                 :                :         {
                              14011                 :             36 :             char       *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
                              14012                 :                : 
                              14013                 :                :             /*
                              14014                 :                :              * Always qualify the function name (format_function_signature
                              14015                 :                :              * won't qualify it).
                              14016                 :                :              */
                              14017                 :             36 :             appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
 3050 tgl@sss.pgh.pa.us       14018                 :             36 :                               fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3837 peter_e@gmx.net         14019                 :             36 :             free(fsig);
                              14020                 :                :         }
                              14021                 :                :         else
 2401 peter@eisentraut.org    14022                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trffromsql field");
                              14023                 :                :     }
                              14024                 :                : 
 3837 peter_e@gmx.net         14025         [ +  - ]:CBC          36 :     if (transform->trftosql)
                              14026                 :                :     {
                              14027         [ +  - ]:             36 :         if (transform->trffromsql)
 2307 drowley@postgresql.o    14028                 :             36 :             appendPQExpBufferStr(defqry, ", ");
                              14029                 :                : 
 3837 peter_e@gmx.net         14030         [ +  - ]:             36 :         if (tosqlFuncInfo)
                              14031                 :                :         {
                              14032                 :             36 :             char       *fsig = format_function_signature(fout, tosqlFuncInfo, true);
                              14033                 :                : 
                              14034                 :                :             /*
                              14035                 :                :              * Always qualify the function name (format_function_signature
                              14036                 :                :              * won't qualify it).
                              14037                 :                :              */
                              14038                 :             36 :             appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
 3050 tgl@sss.pgh.pa.us       14039                 :             36 :                               fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3837 peter_e@gmx.net         14040                 :             36 :             free(fsig);
                              14041                 :                :         }
                              14042                 :                :         else
 2401 peter@eisentraut.org    14043                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trftosql field");
                              14044                 :                :     }
                              14045                 :                : 
 2307 drowley@postgresql.o    14046                 :CBC          36 :     appendPQExpBufferStr(defqry, ");\n");
                              14047                 :                : 
 3837 peter_e@gmx.net         14048                 :             36 :     appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
                              14049                 :                :                       transformType, lanname);
                              14050                 :                : 
 2800 tgl@sss.pgh.pa.us       14051                 :             36 :     appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
                              14052                 :                :                       transformType, lanname);
                              14053                 :                : 
 3837 peter_e@gmx.net         14054         [ +  + ]:             36 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       14055                 :              2 :         binary_upgrade_extension_member(defqry, &transform->dobj,
                              14056                 :              2 :                                         "TRANSFORM", transformargs->data, NULL);
                              14057                 :                : 
 3491 sfrost@snowman.net      14058         [ +  - ]:             36 :     if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14059                 :             36 :         ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    14060                 :             36 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              14061                 :                :                                   .description = "TRANSFORM",
                              14062                 :                :                                   .section = SECTION_PRE_DATA,
                              14063                 :                :                                   .createStmt = defqry->data,
                              14064                 :                :                                   .dropStmt = delqry->data,
                              14065                 :                :                                   .deps = transform->dobj.dependencies,
                              14066                 :                :                                   .nDeps = transform->dobj.nDeps));
                              14067                 :                : 
                              14068                 :                :     /* Dump Transform Comments */
 3491 sfrost@snowman.net      14069         [ -  + ]:             36 :     if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       14070                 :UBC           0 :         dumpComment(fout, "TRANSFORM", transformargs->data,
                              14071                 :                :                     NULL, "",
 3491 sfrost@snowman.net      14072                 :              0 :                     transform->dobj.catId, 0, transform->dobj.dumpId);
                              14073                 :                : 
 3837 peter_e@gmx.net         14074                 :CBC          36 :     free(lanname);
                              14075                 :             36 :     destroyPQExpBuffer(defqry);
                              14076                 :             36 :     destroyPQExpBuffer(delqry);
                              14077                 :             36 :     destroyPQExpBuffer(labelq);
 2800 tgl@sss.pgh.pa.us       14078                 :             36 :     destroyPQExpBuffer(transformargs);
                              14079                 :                : }
                              14080                 :                : 
                              14081                 :                : 
                              14082                 :                : /*
                              14083                 :                :  * dumpOpr
                              14084                 :                :  *    write out a single operator definition
                              14085                 :                :  */
                              14086                 :                : static void
 1720 peter@eisentraut.org    14087                 :           2504 : dumpOpr(Archive *fout, const OprInfo *oprinfo)
                              14088                 :                : {
 3575 tgl@sss.pgh.pa.us       14089                 :           2504 :     DumpOptions *dopt = fout->dopt;
                              14090                 :                :     PQExpBuffer query;
                              14091                 :                :     PQExpBuffer q;
                              14092                 :                :     PQExpBuffer delq;
                              14093                 :                :     PQExpBuffer oprid;
                              14094                 :                :     PQExpBuffer details;
                              14095                 :                :     PGresult   *res;
                              14096                 :                :     int         i_oprkind;
                              14097                 :                :     int         i_oprcode;
                              14098                 :                :     int         i_oprleft;
                              14099                 :                :     int         i_oprright;
                              14100                 :                :     int         i_oprcom;
                              14101                 :                :     int         i_oprnegate;
                              14102                 :                :     int         i_oprrest;
                              14103                 :                :     int         i_oprjoin;
                              14104                 :                :     int         i_oprcanmerge;
                              14105                 :                :     int         i_oprcanhash;
                              14106                 :                :     char       *oprkind;
                              14107                 :                :     char       *oprcode;
                              14108                 :                :     char       *oprleft;
                              14109                 :                :     char       *oprright;
                              14110                 :                :     char       *oprcom;
                              14111                 :                :     char       *oprnegate;
                              14112                 :                :     char       *oprrest;
                              14113                 :                :     char       *oprjoin;
                              14114                 :                :     char       *oprcanmerge;
                              14115                 :                :     char       *oprcanhash;
                              14116                 :                :     char       *oprregproc;
                              14117                 :                :     char       *oprref;
                              14118                 :                : 
                              14119                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    14120         [ +  + ]:           2504 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       14121                 :              6 :         return;
                              14122                 :                : 
                              14123                 :                :     /*
                              14124                 :                :      * some operators are invalid because they were the result of user
                              14125                 :                :      * defining operators before commutators exist
                              14126                 :                :      */
                              14127         [ +  + ]:           2498 :     if (!OidIsValid(oprinfo->oprcode))
                              14128                 :             14 :         return;
                              14129                 :                : 
                              14130                 :           2484 :     query = createPQExpBuffer();
                              14131                 :           2484 :     q = createPQExpBuffer();
                              14132                 :           2484 :     delq = createPQExpBuffer();
                              14133                 :           2484 :     oprid = createPQExpBuffer();
                              14134                 :           2484 :     details = createPQExpBuffer();
                              14135                 :                : 
 1421                         14136         [ +  + ]:           2484 :     if (!fout->is_prepared[PREPQUERY_DUMPOPR])
                              14137                 :                :     {
                              14138                 :                :         /* Set up query for operator-specific details */
                              14139                 :             40 :         appendPQExpBufferStr(query,
                              14140                 :                :                              "PREPARE dumpOpr(pg_catalog.oid) AS\n"
                              14141                 :                :                              "SELECT oprkind, "
                              14142                 :                :                              "oprcode::pg_catalog.regprocedure, "
                              14143                 :                :                              "oprleft::pg_catalog.regtype, "
                              14144                 :                :                              "oprright::pg_catalog.regtype, "
                              14145                 :                :                              "oprcom, "
                              14146                 :                :                              "oprnegate, "
                              14147                 :                :                              "oprrest::pg_catalog.regprocedure, "
                              14148                 :                :                              "oprjoin::pg_catalog.regprocedure, "
                              14149                 :                :                              "oprcanmerge, oprcanhash "
                              14150                 :                :                              "FROM pg_catalog.pg_operator "
                              14151                 :                :                              "WHERE oid = $1");
                              14152                 :                : 
                              14153                 :             40 :         ExecuteSqlStatement(fout, query->data);
                              14154                 :                : 
                              14155                 :             40 :         fout->is_prepared[PREPQUERY_DUMPOPR] = true;
                              14156                 :                :     }
                              14157                 :                : 
                              14158                 :           2484 :     printfPQExpBuffer(query,
                              14159                 :                :                       "EXECUTE dumpOpr('%u')",
                              14160                 :           2484 :                       oprinfo->dobj.catId.oid);
                              14161                 :                : 
 5002 rhaas@postgresql.org    14162                 :           2484 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14163                 :                : 
 8571 tgl@sss.pgh.pa.us       14164                 :           2484 :     i_oprkind = PQfnumber(res, "oprkind");
                              14165                 :           2484 :     i_oprcode = PQfnumber(res, "oprcode");
                              14166                 :           2484 :     i_oprleft = PQfnumber(res, "oprleft");
                              14167                 :           2484 :     i_oprright = PQfnumber(res, "oprright");
                              14168                 :           2484 :     i_oprcom = PQfnumber(res, "oprcom");
                              14169                 :           2484 :     i_oprnegate = PQfnumber(res, "oprnegate");
                              14170                 :           2484 :     i_oprrest = PQfnumber(res, "oprrest");
                              14171                 :           2484 :     i_oprjoin = PQfnumber(res, "oprjoin");
 6883                         14172                 :           2484 :     i_oprcanmerge = PQfnumber(res, "oprcanmerge");
 8571                         14173                 :           2484 :     i_oprcanhash = PQfnumber(res, "oprcanhash");
                              14174                 :                : 
                              14175                 :           2484 :     oprkind = PQgetvalue(res, 0, i_oprkind);
                              14176                 :           2484 :     oprcode = PQgetvalue(res, 0, i_oprcode);
                              14177                 :           2484 :     oprleft = PQgetvalue(res, 0, i_oprleft);
                              14178                 :           2484 :     oprright = PQgetvalue(res, 0, i_oprright);
                              14179                 :           2484 :     oprcom = PQgetvalue(res, 0, i_oprcom);
                              14180                 :           2484 :     oprnegate = PQgetvalue(res, 0, i_oprnegate);
                              14181                 :           2484 :     oprrest = PQgetvalue(res, 0, i_oprrest);
                              14182                 :           2484 :     oprjoin = PQgetvalue(res, 0, i_oprjoin);
 6883                         14183                 :           2484 :     oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
 8571                         14184                 :           2484 :     oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
                              14185                 :                : 
                              14186                 :                :     /* In PG14 upwards postfix operator support does not exist anymore. */
 1866                         14187         [ -  + ]:           2484 :     if (strcmp(oprkind, "r") == 0)
 1866 tgl@sss.pgh.pa.us       14188                 :UBC           0 :         pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
                              14189                 :                :                        oprcode);
                              14190                 :                : 
 1889 peter@eisentraut.org    14191                 :CBC        2484 :     oprregproc = convertRegProcReference(oprcode);
 4258 sfrost@snowman.net      14192         [ +  - ]:           2484 :     if (oprregproc)
                              14193                 :                :     {
 2630 peter_e@gmx.net         14194                 :           2484 :         appendPQExpBuffer(details, "    FUNCTION = %s", oprregproc);
 4258 sfrost@snowman.net      14195                 :           2484 :         free(oprregproc);
                              14196                 :                :     }
                              14197                 :                : 
 8571 tgl@sss.pgh.pa.us       14198                 :           2484 :     appendPQExpBuffer(oprid, "%s (",
 7908                         14199                 :           2484 :                       oprinfo->dobj.name);
                              14200                 :                : 
                              14201                 :                :     /*
                              14202                 :                :      * right unary means there's a left arg and left unary means there's a
                              14203                 :                :      * right arg.  (Although the "r" case is dead code for PG14 and later,
                              14204                 :                :      * continue to support it in case we're dumping from an old server.)
                              14205                 :                :      */
 8571                         14206         [ +  - ]:           2484 :     if (strcmp(oprkind, "r") == 0 ||
                              14207         [ +  + ]:           2484 :         strcmp(oprkind, "b") == 0)
                              14208                 :                :     {
 3302                         14209                 :           2341 :         appendPQExpBuffer(details, ",\n    LEFTARG = %s", oprleft);
                              14210                 :           2341 :         appendPQExpBufferStr(oprid, oprleft);
                              14211                 :                :     }
                              14212                 :                :     else
 4361 heikki.linnakangas@i    14213                 :            143 :         appendPQExpBufferStr(oprid, "NONE");
                              14214                 :                : 
 8571 tgl@sss.pgh.pa.us       14215         [ +  + ]:           2484 :     if (strcmp(oprkind, "l") == 0 ||
                              14216         [ +  - ]:           2341 :         strcmp(oprkind, "b") == 0)
                              14217                 :                :     {
 3302                         14218                 :           2484 :         appendPQExpBuffer(details, ",\n    RIGHTARG = %s", oprright);
                              14219                 :           2484 :         appendPQExpBuffer(oprid, ", %s)", oprright);
                              14220                 :                :     }
                              14221                 :                :     else
 4361 heikki.linnakangas@i    14222                 :UBC           0 :         appendPQExpBufferStr(oprid, ", NONE)");
                              14223                 :                : 
 1889 peter@eisentraut.org    14224                 :CBC        2484 :     oprref = getFormattedOperatorName(oprcom);
 4258 sfrost@snowman.net      14225         [ +  + ]:           2484 :     if (oprref)
                              14226                 :                :     {
                              14227                 :           1661 :         appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
                              14228                 :           1661 :         free(oprref);
                              14229                 :                :     }
                              14230                 :                : 
 1889 peter@eisentraut.org    14231                 :           2484 :     oprref = getFormattedOperatorName(oprnegate);
 4258 sfrost@snowman.net      14232         [ +  + ]:           2484 :     if (oprref)
                              14233                 :                :     {
                              14234                 :           1163 :         appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
                              14235                 :           1163 :         free(oprref);
                              14236                 :                :     }
                              14237                 :                : 
 6883 tgl@sss.pgh.pa.us       14238         [ +  + ]:           2484 :     if (strcmp(oprcanmerge, "t") == 0)
 4361 heikki.linnakangas@i    14239                 :            185 :         appendPQExpBufferStr(details, ",\n    MERGES");
                              14240                 :                : 
 8571 tgl@sss.pgh.pa.us       14241         [ +  + ]:           2484 :     if (strcmp(oprcanhash, "t") == 0)
 4361 heikki.linnakangas@i    14242                 :            138 :         appendPQExpBufferStr(details, ",\n    HASHES");
                              14243                 :                : 
 1889 peter@eisentraut.org    14244                 :           2484 :     oprregproc = convertRegProcReference(oprrest);
 4258 sfrost@snowman.net      14245         [ +  + ]:           2484 :     if (oprregproc)
                              14246                 :                :     {
                              14247                 :           1514 :         appendPQExpBuffer(details, ",\n    RESTRICT = %s", oprregproc);
                              14248                 :           1514 :         free(oprregproc);
                              14249                 :                :     }
                              14250                 :                : 
 1889 peter@eisentraut.org    14251                 :           2484 :     oprregproc = convertRegProcReference(oprjoin);
 4258 sfrost@snowman.net      14252         [ +  + ]:           2484 :     if (oprregproc)
                              14253                 :                :     {
                              14254                 :           1514 :         appendPQExpBuffer(details, ",\n    JOIN = %s", oprregproc);
                              14255                 :           1514 :         free(oprregproc);
                              14256                 :                :     }
                              14257                 :                : 
 8553 tgl@sss.pgh.pa.us       14258                 :           2484 :     appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
 7908                         14259                 :           2484 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
                              14260                 :                :                       oprid->data);
                              14261                 :                : 
 2800                         14262                 :           2484 :     appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
                              14263                 :           2484 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
 7908                         14264                 :           2484 :                       oprinfo->dobj.name, details->data);
                              14265                 :                : 
 4031 alvherre@alvh.no-ip.    14266         [ +  + ]:           2484 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       14267                 :             12 :         binary_upgrade_extension_member(q, &oprinfo->dobj,
                              14268                 :             12 :                                         "OPERATOR", oprid->data,
                              14269                 :             12 :                                         oprinfo->dobj.namespace->dobj.name);
                              14270                 :                : 
 3491 sfrost@snowman.net      14271         [ +  - ]:           2484 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14272                 :           2484 :         ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    14273                 :           2484 :                      ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
                              14274                 :                :                                   .namespace = oprinfo->dobj.namespace->dobj.name,
                              14275                 :                :                                   .owner = oprinfo->rolname,
                              14276                 :                :                                   .description = "OPERATOR",
                              14277                 :                :                                   .section = SECTION_PRE_DATA,
                              14278                 :                :                                   .createStmt = q->data,
                              14279                 :                :                                   .dropStmt = delq->data));
                              14280                 :                : 
                              14281                 :                :     /* Dump Operator Comments */
 3491 sfrost@snowman.net      14282         [ +  + ]:           2484 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       14283                 :           2397 :         dumpComment(fout, "OPERATOR", oprid->data,
 3491 sfrost@snowman.net      14284                 :           2397 :                     oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                              14285                 :           2397 :                     oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
                              14286                 :                : 
 8571 tgl@sss.pgh.pa.us       14287                 :           2484 :     PQclear(res);
                              14288                 :                : 
                              14289                 :           2484 :     destroyPQExpBuffer(query);
                              14290                 :           2484 :     destroyPQExpBuffer(q);
                              14291                 :           2484 :     destroyPQExpBuffer(delq);
                              14292                 :           2484 :     destroyPQExpBuffer(oprid);
                              14293                 :           2484 :     destroyPQExpBuffer(details);
                              14294                 :                : }
                              14295                 :                : 
                              14296                 :                : /*
                              14297                 :                :  * Convert a function reference obtained from pg_operator
                              14298                 :                :  *
                              14299                 :                :  * Returns allocated string of what to print, or NULL if function references
                              14300                 :                :  * is InvalidOid. Returned string is expected to be free'd by the caller.
                              14301                 :                :  *
                              14302                 :                :  * The input is a REGPROCEDURE display; we have to strip the argument-types
                              14303                 :                :  * part.
                              14304                 :                :  */
                              14305                 :                : static char *
 1889 peter@eisentraut.org    14306                 :           7452 : convertRegProcReference(const char *proc)
                              14307                 :                : {
                              14308                 :                :     char       *name;
                              14309                 :                :     char       *paren;
                              14310                 :                :     bool        inquote;
                              14311                 :                : 
                              14312                 :                :     /* In all cases "-" means a null reference */
 8571 tgl@sss.pgh.pa.us       14313         [ +  + ]:           7452 :     if (strcmp(proc, "-") == 0)
                              14314                 :           1940 :         return NULL;
                              14315                 :                : 
 3302                         14316                 :           5512 :     name = pg_strdup(proc);
                              14317                 :                :     /* find non-double-quoted left paren */
                              14318                 :           5512 :     inquote = false;
                              14319         [ +  - ]:          66432 :     for (paren = name; *paren; paren++)
                              14320                 :                :     {
                              14321   [ +  +  +  - ]:          66432 :         if (*paren == '(' && !inquote)
                              14322                 :                :         {
                              14323                 :           5512 :             *paren = '\0';
                              14324                 :           5512 :             break;
                              14325                 :                :         }
                              14326         [ +  + ]:          60920 :         if (*paren == '"')
                              14327                 :             50 :             inquote = !inquote;
                              14328                 :                :     }
                              14329                 :           5512 :     return name;
                              14330                 :                : }
                              14331                 :                : 
                              14332                 :                : /*
                              14333                 :                :  * getFormattedOperatorName - retrieve the operator name for the
                              14334                 :                :  * given operator OID (presented in string form).
                              14335                 :                :  *
                              14336                 :                :  * Returns an allocated string, or NULL if the given OID is invalid.
                              14337                 :                :  * Caller is responsible for free'ing result string.
                              14338                 :                :  *
                              14339                 :                :  * What we produce has the format "OPERATOR(schema.oprname)".  This is only
                              14340                 :                :  * useful in commands where the operator's argument types can be inferred from
                              14341                 :                :  * context.  We always schema-qualify the name, though.  The predecessor to
                              14342                 :                :  * this code tried to skip the schema qualification if possible, but that led
                              14343                 :                :  * to wrong results in corner cases, such as if an operator and its negator
                              14344                 :                :  * are in different schemas.
                              14345                 :                :  */
                              14346                 :                : static char *
 1889 peter@eisentraut.org    14347                 :           5253 : getFormattedOperatorName(const char *oproid)
                              14348                 :                : {
                              14349                 :                :     OprInfo    *oprInfo;
                              14350                 :                : 
                              14351                 :                :     /* In all cases "0" means a null reference */
 2800 tgl@sss.pgh.pa.us       14352         [ +  + ]:           5253 :     if (strcmp(oproid, "0") == 0)
 8571                         14353                 :           2429 :         return NULL;
                              14354                 :                : 
 2800                         14355                 :           2824 :     oprInfo = findOprByOid(atooid(oproid));
                              14356         [ -  + ]:           2824 :     if (oprInfo == NULL)
                              14357                 :                :     {
 2401 peter@eisentraut.org    14358                 :UBC           0 :         pg_log_warning("could not find operator with OID %s",
                              14359                 :                :                        oproid);
 2800 tgl@sss.pgh.pa.us       14360                 :              0 :         return NULL;
                              14361                 :                :     }
                              14362                 :                : 
 2800 tgl@sss.pgh.pa.us       14363                 :CBC        2824 :     return psprintf("OPERATOR(%s.%s)",
                              14364                 :           2824 :                     fmtId(oprInfo->dobj.namespace->dobj.name),
                              14365                 :                :                     oprInfo->dobj.name);
                              14366                 :                : }
                              14367                 :                : 
                              14368                 :                : /*
                              14369                 :                :  * Convert a function OID obtained from pg_ts_parser or pg_ts_template
                              14370                 :                :  *
                              14371                 :                :  * It is sufficient to use REGPROC rather than REGPROCEDURE, since the
                              14372                 :                :  * argument lists of these functions are predetermined.  Note that the
                              14373                 :                :  * caller should ensure we are in the proper schema, because the results
                              14374                 :                :  * are search path dependent!
                              14375                 :                :  */
                              14376                 :                : static char *
 5011 rhaas@postgresql.org    14377                 :            205 : convertTSFunction(Archive *fout, Oid funcOid)
                              14378                 :                : {
                              14379                 :                :     char       *result;
                              14380                 :                :     char        query[128];
                              14381                 :                :     PGresult   *res;
                              14382                 :                : 
 6642 tgl@sss.pgh.pa.us       14383                 :            205 :     snprintf(query, sizeof(query),
                              14384                 :                :              "SELECT '%u'::pg_catalog.regproc", funcOid);
 5002 rhaas@postgresql.org    14385                 :            205 :     res = ExecuteSqlQueryForSingleRow(fout, query);
                              14386                 :                : 
 5085 bruce@momjian.us        14387                 :            205 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              14388                 :                : 
 6642 tgl@sss.pgh.pa.us       14389                 :            205 :     PQclear(res);
                              14390                 :                : 
                              14391                 :            205 :     return result;
                              14392                 :                : }
                              14393                 :                : 
                              14394                 :                : /*
                              14395                 :                :  * dumpAccessMethod
                              14396                 :                :  *    write out a single access method definition
                              14397                 :                :  */
                              14398                 :                : static void
 1720 peter@eisentraut.org    14399                 :             80 : dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
                              14400                 :                : {
 3505 alvherre@alvh.no-ip.    14401                 :             80 :     DumpOptions *dopt = fout->dopt;
                              14402                 :                :     PQExpBuffer q;
                              14403                 :                :     PQExpBuffer delq;
                              14404                 :                :     char       *qamname;
                              14405                 :                : 
                              14406                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    14407         [ +  + ]:             80 :     if (!dopt->dumpSchema)
 3505 alvherre@alvh.no-ip.    14408                 :             12 :         return;
                              14409                 :                : 
                              14410                 :             68 :     q = createPQExpBuffer();
                              14411                 :             68 :     delq = createPQExpBuffer();
                              14412                 :                : 
                              14413                 :             68 :     qamname = pg_strdup(fmtId(aminfo->dobj.name));
                              14414                 :                : 
                              14415                 :             68 :     appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
                              14416                 :                : 
                              14417      [ +  +  - ]:             68 :     switch (aminfo->amtype)
                              14418                 :                :     {
                              14419                 :             32 :         case AMTYPE_INDEX:
 2307 drowley@postgresql.o    14420                 :             32 :             appendPQExpBufferStr(q, "TYPE INDEX ");
 3505 alvherre@alvh.no-ip.    14421                 :             32 :             break;
 2427 andres@anarazel.de      14422                 :             36 :         case AMTYPE_TABLE:
 2307 drowley@postgresql.o    14423                 :             36 :             appendPQExpBufferStr(q, "TYPE TABLE ");
 2427 andres@anarazel.de      14424                 :             36 :             break;
 3505 alvherre@alvh.no-ip.    14425                 :UBC           0 :         default:
 2401 peter@eisentraut.org    14426                 :              0 :             pg_log_warning("invalid type \"%c\" of access method \"%s\"",
                              14427                 :                :                            aminfo->amtype, qamname);
 3505 alvherre@alvh.no-ip.    14428                 :              0 :             destroyPQExpBuffer(q);
                              14429                 :              0 :             destroyPQExpBuffer(delq);
 2800 tgl@sss.pgh.pa.us       14430                 :              0 :             free(qamname);
 3505 alvherre@alvh.no-ip.    14431                 :              0 :             return;
                              14432                 :                :     }
                              14433                 :                : 
 3505 alvherre@alvh.no-ip.    14434                 :CBC          68 :     appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
                              14435                 :                : 
                              14436                 :             68 :     appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
                              14437                 :                :                       qamname);
                              14438                 :                : 
 3312 tgl@sss.pgh.pa.us       14439         [ +  + ]:             68 :     if (dopt->binary_upgrade)
 2800                         14440                 :              4 :         binary_upgrade_extension_member(q, &aminfo->dobj,
                              14441                 :                :                                         "ACCESS METHOD", qamname, NULL);
                              14442                 :                : 
 3429 sfrost@snowman.net      14443         [ +  - ]:             68 :     if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14444                 :             68 :         ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    14445                 :             68 :                      ARCHIVE_OPTS(.tag = aminfo->dobj.name,
                              14446                 :                :                                   .description = "ACCESS METHOD",
                              14447                 :                :                                   .section = SECTION_PRE_DATA,
                              14448                 :                :                                   .createStmt = q->data,
                              14449                 :                :                                   .dropStmt = delq->data));
                              14450                 :                : 
                              14451                 :                :     /* Dump Access Method Comments */
 3429 sfrost@snowman.net      14452         [ -  + ]:             68 :     if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       14453                 :UBC           0 :         dumpComment(fout, "ACCESS METHOD", qamname,
                              14454                 :                :                     NULL, "",
 3429 sfrost@snowman.net      14455                 :              0 :                     aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
                              14456                 :                : 
 3505 alvherre@alvh.no-ip.    14457                 :CBC          68 :     destroyPQExpBuffer(q);
                              14458                 :             68 :     destroyPQExpBuffer(delq);
 2800 tgl@sss.pgh.pa.us       14459                 :             68 :     free(qamname);
                              14460                 :                : }
                              14461                 :                : 
                              14462                 :                : /*
                              14463                 :                :  * dumpOpclass
                              14464                 :                :  *    write out a single operator class definition
                              14465                 :                :  */
                              14466                 :                : static void
 1720 peter@eisentraut.org    14467                 :            660 : dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
                              14468                 :                : {
 3575 tgl@sss.pgh.pa.us       14469                 :            660 :     DumpOptions *dopt = fout->dopt;
                              14470                 :                :     PQExpBuffer query;
                              14471                 :                :     PQExpBuffer q;
                              14472                 :                :     PQExpBuffer delq;
                              14473                 :                :     PQExpBuffer nameusing;
                              14474                 :                :     PGresult   *res;
                              14475                 :                :     int         ntups;
                              14476                 :                :     int         i_opcintype;
                              14477                 :                :     int         i_opckeytype;
                              14478                 :                :     int         i_opcdefault;
                              14479                 :                :     int         i_opcfamily;
                              14480                 :                :     int         i_opcfamilyname;
                              14481                 :                :     int         i_opcfamilynsp;
                              14482                 :                :     int         i_amname;
                              14483                 :                :     int         i_amopstrategy;
                              14484                 :                :     int         i_amopopr;
                              14485                 :                :     int         i_sortfamily;
                              14486                 :                :     int         i_sortfamilynsp;
                              14487                 :                :     int         i_amprocnum;
                              14488                 :                :     int         i_amproc;
                              14489                 :                :     int         i_amproclefttype;
                              14490                 :                :     int         i_amprocrighttype;
                              14491                 :                :     char       *opcintype;
                              14492                 :                :     char       *opckeytype;
                              14493                 :                :     char       *opcdefault;
                              14494                 :                :     char       *opcfamily;
                              14495                 :                :     char       *opcfamilyname;
                              14496                 :                :     char       *opcfamilynsp;
                              14497                 :                :     char       *amname;
                              14498                 :                :     char       *amopstrategy;
                              14499                 :                :     char       *amopopr;
                              14500                 :                :     char       *sortfamily;
                              14501                 :                :     char       *sortfamilynsp;
                              14502                 :                :     char       *amprocnum;
                              14503                 :                :     char       *amproc;
                              14504                 :                :     char       *amproclefttype;
                              14505                 :                :     char       *amprocrighttype;
                              14506                 :                :     bool        needComma;
                              14507                 :                :     int         i;
                              14508                 :                : 
                              14509                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    14510         [ +  + ]:            660 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       14511                 :             18 :         return;
                              14512                 :                : 
                              14513                 :            642 :     query = createPQExpBuffer();
                              14514                 :            642 :     q = createPQExpBuffer();
                              14515                 :            642 :     delq = createPQExpBuffer();
 2800                         14516                 :            642 :     nameusing = createPQExpBuffer();
                              14517                 :                : 
                              14518                 :                :     /* Get additional fields from the pg_opclass row */
 1413                         14519                 :            642 :     appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                              14520                 :                :                       "opckeytype::pg_catalog.regtype, "
                              14521                 :                :                       "opcdefault, opcfamily, "
                              14522                 :                :                       "opfname AS opcfamilyname, "
                              14523                 :                :                       "nspname AS opcfamilynsp, "
                              14524                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
                              14525                 :                :                       "FROM pg_catalog.pg_opclass c "
                              14526                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
                              14527                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14528                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              14529                 :            642 :                       opcinfo->dobj.catId.oid);
                              14530                 :                : 
 5002 rhaas@postgresql.org    14531                 :            642 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14532                 :                : 
 8490 tgl@sss.pgh.pa.us       14533                 :            642 :     i_opcintype = PQfnumber(res, "opcintype");
                              14534                 :            642 :     i_opckeytype = PQfnumber(res, "opckeytype");
                              14535                 :            642 :     i_opcdefault = PQfnumber(res, "opcdefault");
 6852                         14536                 :            642 :     i_opcfamily = PQfnumber(res, "opcfamily");
 5451                         14537                 :            642 :     i_opcfamilyname = PQfnumber(res, "opcfamilyname");
 6852                         14538                 :            642 :     i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
 8490                         14539                 :            642 :     i_amname = PQfnumber(res, "amname");
                              14540                 :                : 
                              14541                 :                :     /* opcintype may still be needed after we PQclear res */
 3076                         14542                 :            642 :     opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
 8490                         14543                 :            642 :     opckeytype = PQgetvalue(res, 0, i_opckeytype);
                              14544                 :            642 :     opcdefault = PQgetvalue(res, 0, i_opcdefault);
                              14545                 :                :     /* opcfamily will still be needed after we PQclear res */
 5085 bruce@momjian.us        14546                 :            642 :     opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
 5451 tgl@sss.pgh.pa.us       14547                 :            642 :     opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
 6852                         14548                 :            642 :     opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
                              14549                 :                :     /* amname will still be needed after we PQclear res */
 5085 bruce@momjian.us        14550                 :            642 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              14551                 :                : 
 8490 tgl@sss.pgh.pa.us       14552                 :            642 :     appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
 2800                         14553                 :            642 :                       fmtQualifiedDumpable(opcinfo));
 8490                         14554                 :            642 :     appendPQExpBuffer(delq, " USING %s;\n",
                              14555                 :                :                       fmtId(amname));
                              14556                 :                : 
                              14557                 :                :     /* Build the fixed portion of the CREATE command */
 8471 peter_e@gmx.net         14558                 :            642 :     appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
 2800 tgl@sss.pgh.pa.us       14559                 :            642 :                       fmtQualifiedDumpable(opcinfo));
 8490                         14560         [ +  + ]:            642 :     if (strcmp(opcdefault, "t") == 0)
 4361 heikki.linnakangas@i    14561                 :            357 :         appendPQExpBufferStr(q, "DEFAULT ");
 6852 tgl@sss.pgh.pa.us       14562                 :            642 :     appendPQExpBuffer(q, "FOR TYPE %s USING %s",
                              14563                 :                :                       opcintype,
                              14564                 :                :                       fmtId(amname));
 3484                         14565         [ +  - ]:            642 :     if (strlen(opcfamilyname) > 0)
                              14566                 :                :     {
 4361 heikki.linnakangas@i    14567                 :            642 :         appendPQExpBufferStr(q, " FAMILY ");
 2800 tgl@sss.pgh.pa.us       14568                 :            642 :         appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
 3770 heikki.linnakangas@i    14569                 :            642 :         appendPQExpBufferStr(q, fmtId(opcfamilyname));
                              14570                 :                :     }
 4361                         14571                 :            642 :     appendPQExpBufferStr(q, " AS\n    ");
                              14572                 :                : 
 8490 tgl@sss.pgh.pa.us       14573                 :            642 :     needComma = false;
                              14574                 :                : 
                              14575         [ +  + ]:            642 :     if (strcmp(opckeytype, "-") != 0)
                              14576                 :                :     {
 8471 peter_e@gmx.net         14577                 :            252 :         appendPQExpBuffer(q, "STORAGE %s",
                              14578                 :                :                           opckeytype);
 8490 tgl@sss.pgh.pa.us       14579                 :            252 :         needComma = true;
                              14580                 :                :     }
                              14581                 :                : 
                              14582                 :            642 :     PQclear(res);
                              14583                 :                : 
                              14584                 :                :     /*
                              14585                 :                :      * Now fetch and print the OPERATOR entries (pg_amop rows).
                              14586                 :                :      *
                              14587                 :                :      * Print only those opfamily members that are tied to the opclass by
                              14588                 :                :      * pg_depend entries.
                              14589                 :                :      */
                              14590                 :            642 :     resetPQExpBuffer(query);
 1413                         14591                 :            642 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              14592                 :                :                       "amopopr::pg_catalog.regoperator, "
                              14593                 :                :                       "opfname AS sortfamily, "
                              14594                 :                :                       "nspname AS sortfamilynsp "
                              14595                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              14596                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              14597                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              14598                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14599                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              14600                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14601                 :                :                       "AND amopfamily = '%s'::pg_catalog.oid "
                              14602                 :                :                       "ORDER BY amopstrategy",
                              14603                 :            642 :                       opcinfo->dobj.catId.oid,
                              14604                 :                :                       opcfamily);
                              14605                 :                : 
 5011 rhaas@postgresql.org    14606                 :            642 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14607                 :                : 
 8490 tgl@sss.pgh.pa.us       14608                 :            642 :     ntups = PQntuples(res);
                              14609                 :                : 
                              14610                 :            642 :     i_amopstrategy = PQfnumber(res, "amopstrategy");
                              14611                 :            642 :     i_amopopr = PQfnumber(res, "amopopr");
 5451                         14612                 :            642 :     i_sortfamily = PQfnumber(res, "sortfamily");
                              14613                 :            642 :     i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
                              14614                 :                : 
 8490                         14615         [ +  + ]:            844 :     for (i = 0; i < ntups; i++)
                              14616                 :                :     {
                              14617                 :            202 :         amopstrategy = PQgetvalue(res, i, i_amopstrategy);
                              14618                 :            202 :         amopopr = PQgetvalue(res, i, i_amopopr);
 5451                         14619                 :            202 :         sortfamily = PQgetvalue(res, i, i_sortfamily);
                              14620                 :            202 :         sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
                              14621                 :                : 
 8490                         14622         [ +  + ]:            202 :         if (needComma)
 4361 heikki.linnakangas@i    14623                 :            128 :             appendPQExpBufferStr(q, " ,\n    ");
                              14624                 :                : 
 8471 peter_e@gmx.net         14625                 :            202 :         appendPQExpBuffer(q, "OPERATOR %s %s",
                              14626                 :                :                           amopstrategy, amopopr);
                              14627                 :                : 
 5451 tgl@sss.pgh.pa.us       14628         [ -  + ]:            202 :         if (strlen(sortfamily) > 0)
                              14629                 :                :         {
 4361 heikki.linnakangas@i    14630                 :UBC           0 :             appendPQExpBufferStr(q, " FOR ORDER BY ");
 2800 tgl@sss.pgh.pa.us       14631                 :              0 :             appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 4361 heikki.linnakangas@i    14632                 :              0 :             appendPQExpBufferStr(q, fmtId(sortfamily));
                              14633                 :                :         }
                              14634                 :                : 
 8490 tgl@sss.pgh.pa.us       14635                 :CBC         202 :         needComma = true;
                              14636                 :                :     }
                              14637                 :                : 
                              14638                 :            642 :     PQclear(res);
                              14639                 :                : 
                              14640                 :                :     /*
                              14641                 :                :      * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              14642                 :                :      *
                              14643                 :                :      * Print only those opfamily members that are tied to the opclass by
                              14644                 :                :      * pg_depend entries.
                              14645                 :                :      *
                              14646                 :                :      * We print the amproclefttype/amprocrighttype even though in most cases
                              14647                 :                :      * the backend could deduce the right values, because of the corner case
                              14648                 :                :      * of a btree sort support function for a cross-type comparison.
                              14649                 :                :      */
                              14650                 :            642 :     resetPQExpBuffer(query);
                              14651                 :                : 
 1413                         14652                 :            642 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              14653                 :                :                       "amproc::pg_catalog.regprocedure, "
                              14654                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              14655                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              14656                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              14657                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              14658                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14659                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              14660                 :                :                       "AND objid = ap.oid "
                              14661                 :                :                       "ORDER BY amprocnum",
                              14662                 :            642 :                       opcinfo->dobj.catId.oid);
                              14663                 :                : 
 5011 rhaas@postgresql.org    14664                 :            642 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14665                 :                : 
 8490 tgl@sss.pgh.pa.us       14666                 :            642 :     ntups = PQntuples(res);
                              14667                 :                : 
                              14668                 :            642 :     i_amprocnum = PQfnumber(res, "amprocnum");
                              14669                 :            642 :     i_amproc = PQfnumber(res, "amproc");
 5073                         14670                 :            642 :     i_amproclefttype = PQfnumber(res, "amproclefttype");
                              14671                 :            642 :     i_amprocrighttype = PQfnumber(res, "amprocrighttype");
                              14672                 :                : 
 8490                         14673         [ +  + ]:            674 :     for (i = 0; i < ntups; i++)
                              14674                 :                :     {
                              14675                 :             32 :         amprocnum = PQgetvalue(res, i, i_amprocnum);
                              14676                 :             32 :         amproc = PQgetvalue(res, i, i_amproc);
 5073                         14677                 :             32 :         amproclefttype = PQgetvalue(res, i, i_amproclefttype);
                              14678                 :             32 :         amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
                              14679                 :                : 
 8490                         14680         [ +  - ]:             32 :         if (needComma)
 4361 heikki.linnakangas@i    14681                 :             32 :             appendPQExpBufferStr(q, " ,\n    ");
                              14682                 :                : 
 5073 tgl@sss.pgh.pa.us       14683                 :             32 :         appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
                              14684                 :                : 
                              14685   [ +  -  +  - ]:             32 :         if (*amproclefttype && *amprocrighttype)
                              14686                 :             32 :             appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
                              14687                 :                : 
                              14688                 :             32 :         appendPQExpBuffer(q, " %s", amproc);
                              14689                 :                : 
 8490                         14690                 :             32 :         needComma = true;
                              14691                 :                :     }
                              14692                 :                : 
                              14693                 :            642 :     PQclear(res);
                              14694                 :                : 
                              14695                 :                :     /*
                              14696                 :                :      * If needComma is still false it means we haven't added anything after
                              14697                 :                :      * the AS keyword.  To avoid printing broken SQL, append a dummy STORAGE
                              14698                 :                :      * clause with the same datatype.  This isn't sanctioned by the
                              14699                 :                :      * documentation, but actually DefineOpClass will treat it as a no-op.
                              14700                 :                :      */
 3076                         14701         [ +  + ]:            642 :     if (!needComma)
                              14702                 :            316 :         appendPQExpBuffer(q, "STORAGE %s", opcintype);
                              14703                 :                : 
 4361 heikki.linnakangas@i    14704                 :            642 :     appendPQExpBufferStr(q, ";\n");
                              14705                 :                : 
 2800 tgl@sss.pgh.pa.us       14706                 :            642 :     appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
                              14707                 :            642 :     appendPQExpBuffer(nameusing, " USING %s",
                              14708                 :                :                       fmtId(amname));
                              14709                 :                : 
 4031 alvherre@alvh.no-ip.    14710         [ +  + ]:            642 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       14711                 :              6 :         binary_upgrade_extension_member(q, &opcinfo->dobj,
                              14712                 :              6 :                                         "OPERATOR CLASS", nameusing->data,
                              14713                 :              6 :                                         opcinfo->dobj.namespace->dobj.name);
                              14714                 :                : 
 3491 sfrost@snowman.net      14715         [ +  - ]:            642 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14716                 :            642 :         ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    14717                 :            642 :                      ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
                              14718                 :                :                                   .namespace = opcinfo->dobj.namespace->dobj.name,
                              14719                 :                :                                   .owner = opcinfo->rolname,
                              14720                 :                :                                   .description = "OPERATOR CLASS",
                              14721                 :                :                                   .section = SECTION_PRE_DATA,
                              14722                 :                :                                   .createStmt = q->data,
                              14723                 :                :                                   .dropStmt = delq->data));
                              14724                 :                : 
                              14725                 :                :     /* Dump Operator Class Comments */
 3491 sfrost@snowman.net      14726         [ -  + ]:            642 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       14727                 :UBC           0 :         dumpComment(fout, "OPERATOR CLASS", nameusing->data,
 3157                         14728                 :              0 :                     opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
 3491 sfrost@snowman.net      14729                 :              0 :                     opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
                              14730                 :                : 
 3076 tgl@sss.pgh.pa.us       14731                 :CBC         642 :     free(opcintype);
                              14732                 :            642 :     free(opcfamily);
 8011                         14733                 :            642 :     free(amname);
 8490                         14734                 :            642 :     destroyPQExpBuffer(query);
                              14735                 :            642 :     destroyPQExpBuffer(q);
                              14736                 :            642 :     destroyPQExpBuffer(delq);
 2800                         14737                 :            642 :     destroyPQExpBuffer(nameusing);
                              14738                 :                : }
                              14739                 :                : 
                              14740                 :                : /*
                              14741                 :                :  * dumpOpfamily
                              14742                 :                :  *    write out a single operator family definition
                              14743                 :                :  *
                              14744                 :                :  * Note: this also dumps any "loose" operator members that aren't bound to a
                              14745                 :                :  * specific opclass within the opfamily.
                              14746                 :                :  */
                              14747                 :                : static void
 1720 peter@eisentraut.org    14748                 :            549 : dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
                              14749                 :                : {
 3575 tgl@sss.pgh.pa.us       14750                 :            549 :     DumpOptions *dopt = fout->dopt;
                              14751                 :                :     PQExpBuffer query;
                              14752                 :                :     PQExpBuffer q;
                              14753                 :                :     PQExpBuffer delq;
                              14754                 :                :     PQExpBuffer nameusing;
                              14755                 :                :     PGresult   *res;
                              14756                 :                :     PGresult   *res_ops;
                              14757                 :                :     PGresult   *res_procs;
                              14758                 :                :     int         ntups;
                              14759                 :                :     int         i_amname;
                              14760                 :                :     int         i_amopstrategy;
                              14761                 :                :     int         i_amopopr;
                              14762                 :                :     int         i_sortfamily;
                              14763                 :                :     int         i_sortfamilynsp;
                              14764                 :                :     int         i_amprocnum;
                              14765                 :                :     int         i_amproc;
                              14766                 :                :     int         i_amproclefttype;
                              14767                 :                :     int         i_amprocrighttype;
                              14768                 :                :     char       *amname;
                              14769                 :                :     char       *amopstrategy;
                              14770                 :                :     char       *amopopr;
                              14771                 :                :     char       *sortfamily;
                              14772                 :                :     char       *sortfamilynsp;
                              14773                 :                :     char       *amprocnum;
                              14774                 :                :     char       *amproc;
                              14775                 :                :     char       *amproclefttype;
                              14776                 :                :     char       *amprocrighttype;
                              14777                 :                :     bool        needComma;
                              14778                 :                :     int         i;
                              14779                 :                : 
                              14780                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    14781         [ +  + ]:            549 :     if (!dopt->dumpSchema)
 6852 tgl@sss.pgh.pa.us       14782                 :             12 :         return;
                              14783                 :                : 
                              14784                 :            537 :     query = createPQExpBuffer();
                              14785                 :            537 :     q = createPQExpBuffer();
                              14786                 :            537 :     delq = createPQExpBuffer();
 2800                         14787                 :            537 :     nameusing = createPQExpBuffer();
                              14788                 :                : 
                              14789                 :                :     /*
                              14790                 :                :      * Fetch only those opfamily members that are tied directly to the
                              14791                 :                :      * opfamily by pg_depend entries.
                              14792                 :                :      */
 1413                         14793                 :            537 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              14794                 :                :                       "amopopr::pg_catalog.regoperator, "
                              14795                 :                :                       "opfname AS sortfamily, "
                              14796                 :                :                       "nspname AS sortfamilynsp "
                              14797                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              14798                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              14799                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              14800                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14801                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              14802                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14803                 :                :                       "AND amopfamily = '%u'::pg_catalog.oid "
                              14804                 :                :                       "ORDER BY amopstrategy",
                              14805                 :            537 :                       opfinfo->dobj.catId.oid,
                              14806                 :            537 :                       opfinfo->dobj.catId.oid);
                              14807                 :                : 
 5011 rhaas@postgresql.org    14808                 :            537 :     res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14809                 :                : 
 6852 tgl@sss.pgh.pa.us       14810                 :            537 :     resetPQExpBuffer(query);
                              14811                 :                : 
                              14812                 :            537 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              14813                 :                :                       "amproc::pg_catalog.regprocedure, "
                              14814                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              14815                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              14816                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              14817                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              14818                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14819                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              14820                 :                :                       "AND objid = ap.oid "
                              14821                 :                :                       "ORDER BY amprocnum",
                              14822                 :            537 :                       opfinfo->dobj.catId.oid);
                              14823                 :                : 
 5011 rhaas@postgresql.org    14824                 :            537 :     res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14825                 :                : 
                              14826                 :                :     /* Get additional fields from the pg_opfamily row */
 6852 tgl@sss.pgh.pa.us       14827                 :            537 :     resetPQExpBuffer(query);
                              14828                 :                : 
                              14829                 :            537 :     appendPQExpBuffer(query, "SELECT "
                              14830                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
                              14831                 :                :                       "FROM pg_catalog.pg_opfamily "
                              14832                 :                :                       "WHERE oid = '%u'::pg_catalog.oid",
                              14833                 :            537 :                       opfinfo->dobj.catId.oid);
                              14834                 :                : 
 5002 rhaas@postgresql.org    14835                 :            537 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14836                 :                : 
 6852 tgl@sss.pgh.pa.us       14837                 :            537 :     i_amname = PQfnumber(res, "amname");
                              14838                 :                : 
                              14839                 :                :     /* amname will still be needed after we PQclear res */
 5085 bruce@momjian.us        14840                 :            537 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              14841                 :                : 
 6852 tgl@sss.pgh.pa.us       14842                 :            537 :     appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
 2800                         14843                 :            537 :                       fmtQualifiedDumpable(opfinfo));
 6852                         14844                 :            537 :     appendPQExpBuffer(delq, " USING %s;\n",
                              14845                 :                :                       fmtId(amname));
                              14846                 :                : 
                              14847                 :                :     /* Build the fixed portion of the CREATE command */
                              14848                 :            537 :     appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
 2800                         14849                 :            537 :                       fmtQualifiedDumpable(opfinfo));
 6852                         14850                 :            537 :     appendPQExpBuffer(q, " USING %s;\n",
                              14851                 :                :                       fmtId(amname));
                              14852                 :                : 
                              14853                 :            537 :     PQclear(res);
                              14854                 :                : 
                              14855                 :                :     /* Do we need an ALTER to add loose members? */
                              14856   [ +  +  +  + ]:            537 :     if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
                              14857                 :                :     {
                              14858                 :             47 :         appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
 2800                         14859                 :             47 :                           fmtQualifiedDumpable(opfinfo));
 6852                         14860                 :             47 :         appendPQExpBuffer(q, " USING %s ADD\n    ",
                              14861                 :                :                           fmtId(amname));
                              14862                 :                : 
                              14863                 :             47 :         needComma = false;
                              14864                 :                : 
                              14865                 :                :         /*
                              14866                 :                :          * Now fetch and print the OPERATOR entries (pg_amop rows).
                              14867                 :                :          */
                              14868                 :             47 :         ntups = PQntuples(res_ops);
                              14869                 :                : 
                              14870                 :             47 :         i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
                              14871                 :             47 :         i_amopopr = PQfnumber(res_ops, "amopopr");
 5451                         14872                 :             47 :         i_sortfamily = PQfnumber(res_ops, "sortfamily");
                              14873                 :             47 :         i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
                              14874                 :                : 
 6852                         14875         [ +  + ]:            207 :         for (i = 0; i < ntups; i++)
                              14876                 :                :         {
                              14877                 :            160 :             amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
                              14878                 :            160 :             amopopr = PQgetvalue(res_ops, i, i_amopopr);
 5451                         14879                 :            160 :             sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
                              14880                 :            160 :             sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
                              14881                 :                : 
 6852                         14882         [ +  + ]:            160 :             if (needComma)
 4361 heikki.linnakangas@i    14883                 :            128 :                 appendPQExpBufferStr(q, " ,\n    ");
                              14884                 :                : 
 6852 tgl@sss.pgh.pa.us       14885                 :            160 :             appendPQExpBuffer(q, "OPERATOR %s %s",
                              14886                 :                :                               amopstrategy, amopopr);
                              14887                 :                : 
 5451                         14888         [ -  + ]:            160 :             if (strlen(sortfamily) > 0)
                              14889                 :                :             {
 4361 heikki.linnakangas@i    14890                 :UBC           0 :                 appendPQExpBufferStr(q, " FOR ORDER BY ");
 2800 tgl@sss.pgh.pa.us       14891                 :              0 :                 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 4361 heikki.linnakangas@i    14892                 :              0 :                 appendPQExpBufferStr(q, fmtId(sortfamily));
                              14893                 :                :             }
                              14894                 :                : 
 6852 tgl@sss.pgh.pa.us       14895                 :CBC         160 :             needComma = true;
                              14896                 :                :         }
                              14897                 :                : 
                              14898                 :                :         /*
                              14899                 :                :          * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              14900                 :                :          */
                              14901                 :             47 :         ntups = PQntuples(res_procs);
                              14902                 :                : 
                              14903                 :             47 :         i_amprocnum = PQfnumber(res_procs, "amprocnum");
                              14904                 :             47 :         i_amproc = PQfnumber(res_procs, "amproc");
                              14905                 :             47 :         i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
                              14906                 :             47 :         i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
                              14907                 :                : 
                              14908         [ +  + ]:            222 :         for (i = 0; i < ntups; i++)
                              14909                 :                :         {
                              14910                 :            175 :             amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
                              14911                 :            175 :             amproc = PQgetvalue(res_procs, i, i_amproc);
                              14912                 :            175 :             amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
                              14913                 :            175 :             amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
                              14914                 :                : 
                              14915         [ +  + ]:            175 :             if (needComma)
 4361 heikki.linnakangas@i    14916                 :            160 :                 appendPQExpBufferStr(q, " ,\n    ");
                              14917                 :                : 
 6852 tgl@sss.pgh.pa.us       14918                 :            175 :             appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
                              14919                 :                :                               amprocnum, amproclefttype, amprocrighttype,
                              14920                 :                :                               amproc);
                              14921                 :                : 
                              14922                 :            175 :             needComma = true;
                              14923                 :                :         }
                              14924                 :                : 
 4361 heikki.linnakangas@i    14925                 :             47 :         appendPQExpBufferStr(q, ";\n");
                              14926                 :                :     }
                              14927                 :                : 
 2800 tgl@sss.pgh.pa.us       14928                 :            537 :     appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
                              14929                 :            537 :     appendPQExpBuffer(nameusing, " USING %s",
                              14930                 :                :                       fmtId(amname));
                              14931                 :                : 
 4031 alvherre@alvh.no-ip.    14932         [ +  + ]:            537 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       14933                 :              9 :         binary_upgrade_extension_member(q, &opfinfo->dobj,
                              14934                 :              9 :                                         "OPERATOR FAMILY", nameusing->data,
                              14935                 :              9 :                                         opfinfo->dobj.namespace->dobj.name);
                              14936                 :                : 
 3491 sfrost@snowman.net      14937         [ +  - ]:            537 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14938                 :            537 :         ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    14939                 :            537 :                      ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
                              14940                 :                :                                   .namespace = opfinfo->dobj.namespace->dobj.name,
                              14941                 :                :                                   .owner = opfinfo->rolname,
                              14942                 :                :                                   .description = "OPERATOR FAMILY",
                              14943                 :                :                                   .section = SECTION_PRE_DATA,
                              14944                 :                :                                   .createStmt = q->data,
                              14945                 :                :                                   .dropStmt = delq->data));
                              14946                 :                : 
                              14947                 :                :     /* Dump Operator Family Comments */
 3491 sfrost@snowman.net      14948         [ -  + ]:            537 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       14949                 :UBC           0 :         dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
 3157                         14950                 :              0 :                     opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
 3491 sfrost@snowman.net      14951                 :              0 :                     opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
                              14952                 :                : 
 6852 tgl@sss.pgh.pa.us       14953                 :CBC         537 :     free(amname);
                              14954                 :            537 :     PQclear(res_ops);
                              14955                 :            537 :     PQclear(res_procs);
                              14956                 :            537 :     destroyPQExpBuffer(query);
                              14957                 :            537 :     destroyPQExpBuffer(q);
                              14958                 :            537 :     destroyPQExpBuffer(delq);
 2800                         14959                 :            537 :     destroyPQExpBuffer(nameusing);
                              14960                 :                : }
                              14961                 :                : 
                              14962                 :                : /*
                              14963                 :                :  * dumpCollation
                              14964                 :                :  *    write out a single collation definition
                              14965                 :                :  */
                              14966                 :                : static void
 1720 peter@eisentraut.org    14967                 :           4643 : dumpCollation(Archive *fout, const CollInfo *collinfo)
                              14968                 :                : {
 3575 tgl@sss.pgh.pa.us       14969                 :           4643 :     DumpOptions *dopt = fout->dopt;
                              14970                 :                :     PQExpBuffer query;
                              14971                 :                :     PQExpBuffer q;
                              14972                 :                :     PQExpBuffer delq;
                              14973                 :                :     char       *qcollname;
                              14974                 :                :     PGresult   *res;
                              14975                 :                :     int         i_collprovider;
                              14976                 :                :     int         i_collisdeterministic;
                              14977                 :                :     int         i_collcollate;
                              14978                 :                :     int         i_collctype;
                              14979                 :                :     int         i_colllocale;
                              14980                 :                :     int         i_collicurules;
                              14981                 :                :     const char *collprovider;
                              14982                 :                :     const char *collcollate;
                              14983                 :                :     const char *collctype;
                              14984                 :                :     const char *colllocale;
                              14985                 :                :     const char *collicurules;
                              14986                 :                : 
                              14987                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    14988         [ +  + ]:           4643 :     if (!dopt->dumpSchema)
 5371 peter_e@gmx.net         14989                 :             12 :         return;
                              14990                 :                : 
                              14991                 :           4631 :     query = createPQExpBuffer();
                              14992                 :           4631 :     q = createPQExpBuffer();
                              14993                 :           4631 :     delq = createPQExpBuffer();
                              14994                 :                : 
 2800 tgl@sss.pgh.pa.us       14995                 :           4631 :     qcollname = pg_strdup(fmtId(collinfo->dobj.name));
                              14996                 :                : 
                              14997                 :                :     /* Get collation-specific details */
 2307 drowley@postgresql.o    14998                 :           4631 :     appendPQExpBufferStr(query, "SELECT ");
                              14999                 :                : 
 3140 peter_e@gmx.net         15000         [ +  - ]:           4631 :     if (fout->remoteVersion >= 100000)
 2307 drowley@postgresql.o    15001                 :           4631 :         appendPQExpBufferStr(query,
                              15002                 :                :                              "collprovider, "
                              15003                 :                :                              "collversion, ");
                              15004                 :                :     else
 2307 drowley@postgresql.o    15005                 :UBC           0 :         appendPQExpBufferStr(query,
                              15006                 :                :                              "'c' AS collprovider, "
                              15007                 :                :                              "NULL AS collversion, ");
                              15008                 :                : 
 2411 peter@eisentraut.org    15009         [ +  - ]:CBC        4631 :     if (fout->remoteVersion >= 120000)
 2307 drowley@postgresql.o    15010                 :           4631 :         appendPQExpBufferStr(query,
                              15011                 :                :                              "collisdeterministic, ");
                              15012                 :                :     else
 2307 drowley@postgresql.o    15013                 :UBC           0 :         appendPQExpBufferStr(query,
                              15014                 :                :                              "true AS collisdeterministic, ");
                              15015                 :                : 
  597 jdavis@postgresql.or    15016         [ +  - ]:CBC        4631 :     if (fout->remoteVersion >= 170000)
                              15017                 :           4631 :         appendPQExpBufferStr(query,
                              15018                 :                :                              "colllocale, ");
  597 jdavis@postgresql.or    15019         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 150000)
 1160 peter@eisentraut.org    15020                 :              0 :         appendPQExpBufferStr(query,
                              15021                 :                :                              "colliculocale AS colllocale, ");
                              15022                 :                :     else
                              15023                 :              0 :         appendPQExpBufferStr(query,
                              15024                 :                :                              "NULL AS colllocale, ");
                              15025                 :                : 
  964 peter@eisentraut.org    15026         [ +  - ]:CBC        4631 :     if (fout->remoteVersion >= 160000)
                              15027                 :           4631 :         appendPQExpBufferStr(query,
                              15028                 :                :                              "collicurules, ");
                              15029                 :                :     else
  964 peter@eisentraut.org    15030                 :UBC           0 :         appendPQExpBufferStr(query,
                              15031                 :                :                              "NULL AS collicurules, ");
                              15032                 :                : 
 2411 peter@eisentraut.org    15033                 :CBC        4631 :     appendPQExpBuffer(query,
                              15034                 :                :                       "collcollate, "
                              15035                 :                :                       "collctype "
                              15036                 :                :                       "FROM pg_catalog.pg_collation c "
                              15037                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              15038                 :           4631 :                       collinfo->dobj.catId.oid);
                              15039                 :                : 
 5002 rhaas@postgresql.org    15040                 :           4631 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              15041                 :                : 
 3140 peter_e@gmx.net         15042                 :           4631 :     i_collprovider = PQfnumber(res, "collprovider");
 2411 peter@eisentraut.org    15043                 :           4631 :     i_collisdeterministic = PQfnumber(res, "collisdeterministic");
 5371 peter_e@gmx.net         15044                 :           4631 :     i_collcollate = PQfnumber(res, "collcollate");
                              15045                 :           4631 :     i_collctype = PQfnumber(res, "collctype");
  597 jdavis@postgresql.or    15046                 :           4631 :     i_colllocale = PQfnumber(res, "colllocale");
  964 peter@eisentraut.org    15047                 :           4631 :     i_collicurules = PQfnumber(res, "collicurules");
                              15048                 :                : 
 3140 peter_e@gmx.net         15049                 :           4631 :     collprovider = PQgetvalue(res, 0, i_collprovider);
                              15050                 :                : 
 1160 peter@eisentraut.org    15051         [ +  + ]:           4631 :     if (!PQgetisnull(res, 0, i_collcollate))
                              15052                 :           2014 :         collcollate = PQgetvalue(res, 0, i_collcollate);
                              15053                 :                :     else
                              15054                 :           2617 :         collcollate = NULL;
                              15055                 :                : 
                              15056         [ +  + ]:           4631 :     if (!PQgetisnull(res, 0, i_collctype))
                              15057                 :           2014 :         collctype = PQgetvalue(res, 0, i_collctype);
                              15058                 :                :     else
                              15059                 :           2617 :         collctype = NULL;
                              15060                 :                : 
                              15061                 :                :     /*
                              15062                 :                :      * Before version 15, collcollate and collctype were of type NAME and
                              15063                 :                :      * non-nullable. Treat empty strings as NULL for consistency.
                              15064                 :                :      */
  797 jdavis@postgresql.or    15065         [ -  + ]:           4631 :     if (fout->remoteVersion < 150000)
                              15066                 :                :     {
  797 jdavis@postgresql.or    15067         [ #  # ]:UBC           0 :         if (collcollate[0] == '\0')
                              15068                 :              0 :             collcollate = NULL;
                              15069         [ #  # ]:              0 :         if (collctype[0] == '\0')
                              15070                 :              0 :             collctype = NULL;
                              15071                 :                :     }
                              15072                 :                : 
  597 jdavis@postgresql.or    15073         [ +  + ]:CBC        4631 :     if (!PQgetisnull(res, 0, i_colllocale))
                              15074                 :           2614 :         colllocale = PQgetvalue(res, 0, i_colllocale);
                              15075                 :                :     else
                              15076                 :           2017 :         colllocale = NULL;
                              15077                 :                : 
  964 peter@eisentraut.org    15078         [ -  + ]:           4631 :     if (!PQgetisnull(res, 0, i_collicurules))
  964 peter@eisentraut.org    15079                 :UBC           0 :         collicurules = PQgetvalue(res, 0, i_collicurules);
                              15080                 :                :     else
  964 peter@eisentraut.org    15081                 :CBC        4631 :         collicurules = NULL;
                              15082                 :                : 
 2800 tgl@sss.pgh.pa.us       15083                 :           4631 :     appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
                              15084                 :           4631 :                       fmtQualifiedDumpable(collinfo));
                              15085                 :                : 
 3140 peter_e@gmx.net         15086                 :           4631 :     appendPQExpBuffer(q, "CREATE COLLATION %s (",
 2800 tgl@sss.pgh.pa.us       15087                 :           4631 :                       fmtQualifiedDumpable(collinfo));
                              15088                 :                : 
 3140 peter_e@gmx.net         15089                 :           4631 :     appendPQExpBufferStr(q, "provider = ");
  593 jdavis@postgresql.or    15090         [ +  + ]:           4631 :     if (collprovider[0] == 'b')
                              15091                 :             19 :         appendPQExpBufferStr(q, "builtin");
                              15092         [ +  + ]:           4612 :     else if (collprovider[0] == 'c')
 3140 peter_e@gmx.net         15093                 :           2014 :         appendPQExpBufferStr(q, "libc");
                              15094         [ +  + ]:           2598 :     else if (collprovider[0] == 'i')
                              15095                 :           2595 :         appendPQExpBufferStr(q, "icu");
 3058                         15096         [ +  - ]:              3 :     else if (collprovider[0] == 'd')
                              15097                 :                :         /* to allow dumping pg_catalog; not accepted on input */
                              15098                 :              3 :         appendPQExpBufferStr(q, "default");
                              15099                 :                :     else
 1298 tgl@sss.pgh.pa.us       15100                 :UBC           0 :         pg_fatal("unrecognized collation provider: %s",
                              15101                 :                :                  collprovider);
                              15102                 :                : 
 2411 peter@eisentraut.org    15103         [ -  + ]:CBC        4631 :     if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
 2411 peter@eisentraut.org    15104                 :UBC           0 :         appendPQExpBufferStr(q, ", deterministic = false");
                              15105                 :                : 
  797 jdavis@postgresql.or    15106         [ +  + ]:CBC        4631 :     if (collprovider[0] == 'd')
                              15107                 :                :     {
  597                         15108   [ +  -  +  -  :              3 :         if (collcollate || collctype || colllocale || collicurules)
                                        +  -  -  + ]
  797 jdavis@postgresql.or    15109                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15110                 :                : 
                              15111                 :                :         /* no locale -- the default collation cannot be reloaded anyway */
                              15112                 :                :     }
  593 jdavis@postgresql.or    15113         [ +  + ]:CBC        4628 :     else if (collprovider[0] == 'b')
                              15114                 :                :     {
                              15115   [ +  -  +  -  :             19 :         if (collcollate || collctype || !colllocale || collicurules)
                                        +  -  -  + ]
  593 jdavis@postgresql.or    15116                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15117                 :                : 
  593 jdavis@postgresql.or    15118                 :CBC          19 :         appendPQExpBufferStr(q, ", locale = ");
                              15119         [ +  - ]:             19 :         appendStringLiteralAH(q, colllocale ? colllocale : "",
                              15120                 :                :                               fout);
                              15121                 :                :     }
  797                         15122         [ +  + ]:           4609 :     else if (collprovider[0] == 'i')
                              15123                 :                :     {
                              15124         [ +  - ]:           2595 :         if (fout->remoteVersion >= 150000)
                              15125                 :                :         {
  597                         15126   [ +  -  +  -  :           2595 :             if (collcollate || collctype || !colllocale)
                                              -  + ]
  797 jdavis@postgresql.or    15127                 :UBC           0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              15128                 :                : 
  797 jdavis@postgresql.or    15129                 :CBC        2595 :             appendPQExpBufferStr(q, ", locale = ");
  597                         15130         [ +  - ]:           2595 :             appendStringLiteralAH(q, colllocale ? colllocale : "",
                              15131                 :                :                                   fout);
                              15132                 :                :         }
                              15133                 :                :         else
                              15134                 :                :         {
  597 jdavis@postgresql.or    15135   [ #  #  #  #  :UBC           0 :             if (!collcollate || !collctype || colllocale ||
                                              #  # ]
  797                         15136         [ #  # ]:              0 :                 strcmp(collcollate, collctype) != 0)
                              15137                 :              0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              15138                 :                : 
 1160 peter@eisentraut.org    15139                 :              0 :             appendPQExpBufferStr(q, ", locale = ");
  797 jdavis@postgresql.or    15140         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              15141                 :                :         }
                              15142                 :                : 
  797 jdavis@postgresql.or    15143         [ -  + ]:CBC        2595 :         if (collicurules)
                              15144                 :                :         {
  797 jdavis@postgresql.or    15145                 :UBC           0 :             appendPQExpBufferStr(q, ", rules = ");
                              15146         [ #  # ]:              0 :             appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
                              15147                 :                :         }
                              15148                 :                :     }
  797 jdavis@postgresql.or    15149         [ +  - ]:CBC        2014 :     else if (collprovider[0] == 'c')
                              15150                 :                :     {
  597                         15151   [ +  -  +  -  :           2014 :         if (colllocale || collicurules || !collcollate || !collctype)
                                        +  -  -  + ]
  797 jdavis@postgresql.or    15152                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15153                 :                : 
  797 jdavis@postgresql.or    15154   [ +  -  +  -  :CBC        2014 :         if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
                                              +  - ]
                              15155                 :                :         {
                              15156                 :           2014 :             appendPQExpBufferStr(q, ", locale = ");
                              15157         [ +  - ]:           2014 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              15158                 :                :         }
                              15159                 :                :         else
                              15160                 :                :         {
 1160 peter@eisentraut.org    15161                 :UBC           0 :             appendPQExpBufferStr(q, ", lc_collate = ");
  797 jdavis@postgresql.or    15162         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
 1160 peter@eisentraut.org    15163                 :              0 :             appendPQExpBufferStr(q, ", lc_ctype = ");
  797 jdavis@postgresql.or    15164         [ #  # ]:              0 :             appendStringLiteralAH(q, collctype ? collctype : "", fout);
                              15165                 :                :         }
                              15166                 :                :     }
                              15167                 :                :     else
  783 peter@eisentraut.org    15168                 :              0 :         pg_fatal("unrecognized collation provider: %s", collprovider);
                              15169                 :                : 
                              15170                 :                :     /*
                              15171                 :                :      * For binary upgrade, carry over the collation version.  For normal
                              15172                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                              15173                 :                :      */
 1634 tmunro@postgresql.or    15174         [ +  + ]:CBC        4631 :     if (dopt->binary_upgrade)
                              15175                 :                :     {
                              15176                 :                :         int         i_collversion;
                              15177                 :                : 
                              15178                 :              5 :         i_collversion = PQfnumber(res, "collversion");
                              15179         [ +  + ]:              5 :         if (!PQgetisnull(res, 0, i_collversion))
                              15180                 :                :         {
                              15181                 :              4 :             appendPQExpBufferStr(q, ", version = ");
                              15182                 :              4 :             appendStringLiteralAH(q,
                              15183                 :                :                                   PQgetvalue(res, 0, i_collversion),
                              15184                 :                :                                   fout);
                              15185                 :                :         }
                              15186                 :                :     }
                              15187                 :                : 
 4361 heikki.linnakangas@i    15188                 :           4631 :     appendPQExpBufferStr(q, ");\n");
                              15189                 :                : 
 4031 alvherre@alvh.no-ip.    15190         [ +  + ]:           4631 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15191                 :              5 :         binary_upgrade_extension_member(q, &collinfo->dobj,
                              15192                 :                :                                         "COLLATION", qcollname,
                              15193                 :              5 :                                         collinfo->dobj.namespace->dobj.name);
                              15194                 :                : 
 3491 sfrost@snowman.net      15195         [ +  - ]:           4631 :     if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15196                 :           4631 :         ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15197                 :           4631 :                      ARCHIVE_OPTS(.tag = collinfo->dobj.name,
                              15198                 :                :                                   .namespace = collinfo->dobj.namespace->dobj.name,
                              15199                 :                :                                   .owner = collinfo->rolname,
                              15200                 :                :                                   .description = "COLLATION",
                              15201                 :                :                                   .section = SECTION_PRE_DATA,
                              15202                 :                :                                   .createStmt = q->data,
                              15203                 :                :                                   .dropStmt = delq->data));
                              15204                 :                : 
                              15205                 :                :     /* Dump Collation Comments */
 3491 sfrost@snowman.net      15206         [ +  + ]:           4631 :     if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15207                 :           2557 :         dumpComment(fout, "COLLATION", qcollname,
 3491 sfrost@snowman.net      15208                 :           2557 :                     collinfo->dobj.namespace->dobj.name, collinfo->rolname,
                              15209                 :           2557 :                     collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
                              15210                 :                : 
 5371 peter_e@gmx.net         15211                 :           4631 :     PQclear(res);
                              15212                 :                : 
                              15213                 :           4631 :     destroyPQExpBuffer(query);
                              15214                 :           4631 :     destroyPQExpBuffer(q);
                              15215                 :           4631 :     destroyPQExpBuffer(delq);
 2800 tgl@sss.pgh.pa.us       15216                 :           4631 :     free(qcollname);
                              15217                 :                : }
                              15218                 :                : 
                              15219                 :                : /*
                              15220                 :                :  * dumpConversion
                              15221                 :                :  *    write out a single conversion definition
                              15222                 :                :  */
                              15223                 :                : static void
 1720 peter@eisentraut.org    15224                 :            422 : dumpConversion(Archive *fout, const ConvInfo *convinfo)
                              15225                 :                : {
 3575 tgl@sss.pgh.pa.us       15226                 :            422 :     DumpOptions *dopt = fout->dopt;
                              15227                 :                :     PQExpBuffer query;
                              15228                 :                :     PQExpBuffer q;
                              15229                 :                :     PQExpBuffer delq;
                              15230                 :                :     char       *qconvname;
                              15231                 :                :     PGresult   *res;
                              15232                 :                :     int         i_conforencoding;
                              15233                 :                :     int         i_contoencoding;
                              15234                 :                :     int         i_conproc;
                              15235                 :                :     int         i_condefault;
                              15236                 :                :     const char *conforencoding;
                              15237                 :                :     const char *contoencoding;
                              15238                 :                :     const char *conproc;
                              15239                 :                :     bool        condefault;
                              15240                 :                : 
                              15241                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15242         [ +  + ]:            422 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       15243                 :              6 :         return;
                              15244                 :                : 
                              15245                 :            416 :     query = createPQExpBuffer();
                              15246                 :            416 :     q = createPQExpBuffer();
                              15247                 :            416 :     delq = createPQExpBuffer();
                              15248                 :                : 
 2800                         15249                 :            416 :     qconvname = pg_strdup(fmtId(convinfo->dobj.name));
                              15250                 :                : 
                              15251                 :                :     /* Get conversion-specific details */
 5313 peter_e@gmx.net         15252                 :            416 :     appendPQExpBuffer(query, "SELECT "
                              15253                 :                :                       "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
                              15254                 :                :                       "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
                              15255                 :                :                       "conproc, condefault "
                              15256                 :                :                       "FROM pg_catalog.pg_conversion c "
                              15257                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
 7996 tgl@sss.pgh.pa.us       15258                 :            416 :                       convinfo->dobj.catId.oid);
                              15259                 :                : 
 5002 rhaas@postgresql.org    15260                 :            416 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              15261                 :                : 
 8011 tgl@sss.pgh.pa.us       15262                 :            416 :     i_conforencoding = PQfnumber(res, "conforencoding");
                              15263                 :            416 :     i_contoencoding = PQfnumber(res, "contoencoding");
                              15264                 :            416 :     i_conproc = PQfnumber(res, "conproc");
                              15265                 :            416 :     i_condefault = PQfnumber(res, "condefault");
                              15266                 :                : 
                              15267                 :            416 :     conforencoding = PQgetvalue(res, 0, i_conforencoding);
                              15268                 :            416 :     contoencoding = PQgetvalue(res, 0, i_contoencoding);
                              15269                 :            416 :     conproc = PQgetvalue(res, 0, i_conproc);
                              15270                 :            416 :     condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
                              15271                 :                : 
 2800                         15272                 :            416 :     appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
                              15273                 :            416 :                       fmtQualifiedDumpable(convinfo));
                              15274                 :                : 
 8011                         15275         [ +  - ]:            416 :     appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                              15276                 :                :                       (condefault) ? "DEFAULT " : "",
 2800                         15277                 :            416 :                       fmtQualifiedDumpable(convinfo));
 7092                         15278                 :            416 :     appendStringLiteralAH(q, conforencoding, fout);
 4361 heikki.linnakangas@i    15279                 :            416 :     appendPQExpBufferStr(q, " TO ");
 7092 tgl@sss.pgh.pa.us       15280                 :            416 :     appendStringLiteralAH(q, contoencoding, fout);
                              15281                 :                :     /* regproc output is already sufficiently quoted */
 8011                         15282                 :            416 :     appendPQExpBuffer(q, " FROM %s;\n", conproc);
                              15283                 :                : 
 4031 alvherre@alvh.no-ip.    15284         [ +  + ]:            416 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15285                 :              1 :         binary_upgrade_extension_member(q, &convinfo->dobj,
                              15286                 :                :                                         "CONVERSION", qconvname,
                              15287                 :              1 :                                         convinfo->dobj.namespace->dobj.name);
                              15288                 :                : 
 3491 sfrost@snowman.net      15289         [ +  - ]:            416 :     if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15290                 :            416 :         ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15291                 :            416 :                      ARCHIVE_OPTS(.tag = convinfo->dobj.name,
                              15292                 :                :                                   .namespace = convinfo->dobj.namespace->dobj.name,
                              15293                 :                :                                   .owner = convinfo->rolname,
                              15294                 :                :                                   .description = "CONVERSION",
                              15295                 :                :                                   .section = SECTION_PRE_DATA,
                              15296                 :                :                                   .createStmt = q->data,
                              15297                 :                :                                   .dropStmt = delq->data));
                              15298                 :                : 
                              15299                 :                :     /* Dump Conversion Comments */
 3491 sfrost@snowman.net      15300         [ +  - ]:            416 :     if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15301                 :            416 :         dumpComment(fout, "CONVERSION", qconvname,
 3491 sfrost@snowman.net      15302                 :            416 :                     convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                              15303                 :            416 :                     convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
                              15304                 :                : 
 7996 tgl@sss.pgh.pa.us       15305                 :            416 :     PQclear(res);
                              15306                 :                : 
                              15307                 :            416 :     destroyPQExpBuffer(query);
                              15308                 :            416 :     destroyPQExpBuffer(q);
                              15309                 :            416 :     destroyPQExpBuffer(delq);
 2800                         15310                 :            416 :     free(qconvname);
                              15311                 :                : }
                              15312                 :                : 
                              15313                 :                : /*
                              15314                 :                :  * format_aggregate_signature: generate aggregate name and argument list
                              15315                 :                :  *
                              15316                 :                :  * The argument type names are qualified if needed.  The aggregate name
                              15317                 :                :  * is never qualified.
                              15318                 :                :  */
                              15319                 :                : static char *
 1720 peter@eisentraut.org    15320                 :            285 : format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
                              15321                 :                : {
                              15322                 :                :     PQExpBufferData buf;
                              15323                 :                :     int         j;
                              15324                 :                : 
 8562 peter_e@gmx.net         15325                 :            285 :     initPQExpBuffer(&buf);
 8516 bruce@momjian.us        15326         [ -  + ]:            285 :     if (honor_quotes)
 4361 heikki.linnakangas@i    15327                 :UBC           0 :         appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
                              15328                 :                :     else
 4361 heikki.linnakangas@i    15329                 :CBC         285 :         appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
                              15330                 :                : 
 7032 tgl@sss.pgh.pa.us       15331         [ +  + ]:            285 :     if (agginfo->aggfn.nargs == 0)
 2307 drowley@postgresql.o    15332                 :             40 :         appendPQExpBufferStr(&buf, "(*)");
                              15333                 :                :     else
                              15334                 :                :     {
 4361 heikki.linnakangas@i    15335                 :            245 :         appendPQExpBufferChar(&buf, '(');
 7032 tgl@sss.pgh.pa.us       15336         [ +  + ]:            535 :         for (j = 0; j < agginfo->aggfn.nargs; j++)
                              15337         [ +  + ]:            290 :             appendPQExpBuffer(&buf, "%s%s",
                              15338                 :                :                               (j > 0) ? ", " : "",
                              15339                 :                :                               getFormattedTypeName(fout,
 1510                         15340                 :            290 :                                                    agginfo->aggfn.argtypes[j],
                              15341                 :                :                                                    zeroIsError));
 4361 heikki.linnakangas@i    15342                 :            245 :         appendPQExpBufferChar(&buf, ')');
                              15343                 :                :     }
 8562 peter_e@gmx.net         15344                 :            285 :     return buf.data;
                              15345                 :                : }
                              15346                 :                : 
                              15347                 :                : /*
                              15348                 :                :  * dumpAgg
                              15349                 :                :  *    write out a single aggregate definition
                              15350                 :                :  */
                              15351                 :                : static void
 1720 peter@eisentraut.org    15352                 :            292 : dumpAgg(Archive *fout, const AggInfo *agginfo)
                              15353                 :                : {
 3575 tgl@sss.pgh.pa.us       15354                 :            292 :     DumpOptions *dopt = fout->dopt;
                              15355                 :                :     PQExpBuffer query;
                              15356                 :                :     PQExpBuffer q;
                              15357                 :                :     PQExpBuffer delq;
                              15358                 :                :     PQExpBuffer details;
                              15359                 :                :     char       *aggsig;         /* identity signature */
 3050                         15360                 :            292 :     char       *aggfullsig = NULL;  /* full signature */
                              15361                 :                :     char       *aggsig_tag;
                              15362                 :                :     PGresult   *res;
                              15363                 :                :     int         i_agginitval;
                              15364                 :                :     int         i_aggminitval;
                              15365                 :                :     const char *aggtransfn;
                              15366                 :                :     const char *aggfinalfn;
                              15367                 :                :     const char *aggcombinefn;
                              15368                 :                :     const char *aggserialfn;
                              15369                 :                :     const char *aggdeserialfn;
                              15370                 :                :     const char *aggmtransfn;
                              15371                 :                :     const char *aggminvtransfn;
                              15372                 :                :     const char *aggmfinalfn;
                              15373                 :                :     bool        aggfinalextra;
                              15374                 :                :     bool        aggmfinalextra;
                              15375                 :                :     char        aggfinalmodify;
                              15376                 :                :     char        aggmfinalmodify;
                              15377                 :                :     const char *aggsortop;
                              15378                 :                :     char       *aggsortconvop;
                              15379                 :                :     char        aggkind;
                              15380                 :                :     const char *aggtranstype;
                              15381                 :                :     const char *aggtransspace;
                              15382                 :                :     const char *aggmtranstype;
                              15383                 :                :     const char *aggmtransspace;
                              15384                 :                :     const char *agginitval;
                              15385                 :                :     const char *aggminitval;
                              15386                 :                :     const char *proparallel;
                              15387                 :                :     char        defaultfinalmodify;
                              15388                 :                : 
                              15389                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15390         [ +  + ]:            292 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       15391                 :              7 :         return;
                              15392                 :                : 
                              15393                 :            285 :     query = createPQExpBuffer();
                              15394                 :            285 :     q = createPQExpBuffer();
                              15395                 :            285 :     delq = createPQExpBuffer();
                              15396                 :            285 :     details = createPQExpBuffer();
                              15397                 :                : 
 1421                         15398         [ +  + ]:            285 :     if (!fout->is_prepared[PREPQUERY_DUMPAGG])
                              15399                 :                :     {
                              15400                 :                :         /* Set up query for aggregate-specific details */
 1838 drowley@postgresql.o    15401                 :             55 :         appendPQExpBufferStr(query,
                              15402                 :                :                              "PREPARE dumpAgg(pg_catalog.oid) AS\n");
                              15403                 :                : 
                              15404                 :             55 :         appendPQExpBufferStr(query,
                              15405                 :                :                              "SELECT "
                              15406                 :                :                              "aggtransfn,\n"
                              15407                 :                :                              "aggfinalfn,\n"
                              15408                 :                :                              "aggtranstype::pg_catalog.regtype,\n"
                              15409                 :                :                              "agginitval,\n"
                              15410                 :                :                              "aggsortop,\n"
                              15411                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              15412                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
                              15413                 :                : 
 1421 tgl@sss.pgh.pa.us       15414         [ +  - ]:             55 :         if (fout->remoteVersion >= 90400)
                              15415                 :             55 :             appendPQExpBufferStr(query,
                              15416                 :                :                                  "aggkind,\n"
                              15417                 :                :                                  "aggmtransfn,\n"
                              15418                 :                :                                  "aggminvtransfn,\n"
                              15419                 :                :                                  "aggmfinalfn,\n"
                              15420                 :                :                                  "aggmtranstype::pg_catalog.regtype,\n"
                              15421                 :                :                                  "aggfinalextra,\n"
                              15422                 :                :                                  "aggmfinalextra,\n"
                              15423                 :                :                                  "aggtransspace,\n"
                              15424                 :                :                                  "aggmtransspace,\n"
                              15425                 :                :                                  "aggminitval,\n");
                              15426                 :                :         else
 1421 tgl@sss.pgh.pa.us       15427                 :UBC           0 :             appendPQExpBufferStr(query,
                              15428                 :                :                                  "'n' AS aggkind,\n"
                              15429                 :                :                                  "'-' AS aggmtransfn,\n"
                              15430                 :                :                                  "'-' AS aggminvtransfn,\n"
                              15431                 :                :                                  "'-' AS aggmfinalfn,\n"
                              15432                 :                :                                  "0 AS aggmtranstype,\n"
                              15433                 :                :                                  "false AS aggfinalextra,\n"
                              15434                 :                :                                  "false AS aggmfinalextra,\n"
                              15435                 :                :                                  "0 AS aggtransspace,\n"
                              15436                 :                :                                  "0 AS aggmtransspace,\n"
                              15437                 :                :                                  "NULL AS aggminitval,\n");
                              15438                 :                : 
 1421 tgl@sss.pgh.pa.us       15439         [ +  - ]:CBC          55 :         if (fout->remoteVersion >= 90600)
                              15440                 :             55 :             appendPQExpBufferStr(query,
                              15441                 :                :                                  "aggcombinefn,\n"
                              15442                 :                :                                  "aggserialfn,\n"
                              15443                 :                :                                  "aggdeserialfn,\n"
                              15444                 :                :                                  "proparallel,\n");
                              15445                 :                :         else
 1421 tgl@sss.pgh.pa.us       15446                 :UBC           0 :             appendPQExpBufferStr(query,
                              15447                 :                :                                  "'-' AS aggcombinefn,\n"
                              15448                 :                :                                  "'-' AS aggserialfn,\n"
                              15449                 :                :                                  "'-' AS aggdeserialfn,\n"
                              15450                 :                :                                  "'u' AS proparallel,\n");
                              15451                 :                : 
 1421 tgl@sss.pgh.pa.us       15452         [ +  - ]:CBC          55 :         if (fout->remoteVersion >= 110000)
                              15453                 :             55 :             appendPQExpBufferStr(query,
                              15454                 :                :                                  "aggfinalmodify,\n"
                              15455                 :                :                                  "aggmfinalmodify\n");
                              15456                 :                :         else
 1421 tgl@sss.pgh.pa.us       15457                 :UBC           0 :             appendPQExpBufferStr(query,
                              15458                 :                :                                  "'0' AS aggfinalmodify,\n"
                              15459                 :                :                                  "'0' AS aggmfinalmodify\n");
                              15460                 :                : 
 1838 drowley@postgresql.o    15461                 :CBC          55 :         appendPQExpBufferStr(query,
                              15462                 :                :                              "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                              15463                 :                :                              "WHERE a.aggfnoid = p.oid "
                              15464                 :                :                              "AND p.oid = $1");
                              15465                 :                : 
 1421 tgl@sss.pgh.pa.us       15466                 :             55 :         ExecuteSqlStatement(fout, query->data);
                              15467                 :                : 
                              15468                 :             55 :         fout->is_prepared[PREPQUERY_DUMPAGG] = true;
                              15469                 :                :     }
                              15470                 :                : 
                              15471                 :            285 :     printfPQExpBuffer(query,
                              15472                 :                :                       "EXECUTE dumpAgg('%u')",
 1930 peter@eisentraut.org    15473                 :            285 :                       agginfo->aggfn.dobj.catId.oid);
                              15474                 :                : 
 5002 rhaas@postgresql.org    15475                 :            285 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              15476                 :                : 
 8571 tgl@sss.pgh.pa.us       15477                 :            285 :     i_agginitval = PQfnumber(res, "agginitval");
 4216                         15478                 :            285 :     i_aggminitval = PQfnumber(res, "aggminitval");
                              15479                 :                : 
 1930 peter@eisentraut.org    15480                 :            285 :     aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
                              15481                 :            285 :     aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
                              15482                 :            285 :     aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
                              15483                 :            285 :     aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
                              15484                 :            285 :     aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
                              15485                 :            285 :     aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
                              15486                 :            285 :     aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
                              15487                 :            285 :     aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
                              15488                 :            285 :     aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
                              15489                 :            285 :     aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
                              15490                 :            285 :     aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
                              15491                 :            285 :     aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
                              15492                 :            285 :     aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
                              15493                 :            285 :     aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
                              15494                 :            285 :     aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
                              15495                 :            285 :     aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
                              15496                 :            285 :     aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
                              15497                 :            285 :     aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
 8571 tgl@sss.pgh.pa.us       15498                 :            285 :     agginitval = PQgetvalue(res, 0, i_agginitval);
 4216                         15499                 :            285 :     aggminitval = PQgetvalue(res, 0, i_aggminitval);
 1930 peter@eisentraut.org    15500                 :            285 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
                              15501                 :                : 
                              15502                 :                :     {
                              15503                 :                :         char       *funcargs;
                              15504                 :                :         char       *funciargs;
                              15505                 :                : 
 4437 tgl@sss.pgh.pa.us       15506                 :            285 :         funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              15507                 :            285 :         funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              15508                 :            285 :         aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
                              15509                 :            285 :         aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
                              15510                 :                :     }
                              15511                 :                : 
 7996                         15512                 :            285 :     aggsig_tag = format_aggregate_signature(agginfo, fout, false);
                              15513                 :                : 
                              15514                 :                :     /* identify default modify flag for aggkind (must match DefineAggregate) */
 2935                         15515         [ +  + ]:            285 :     defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
                              15516                 :                :     /* replace omitted flags for old versions */
                              15517         [ -  + ]:            285 :     if (aggfinalmodify == '0')
 2935 tgl@sss.pgh.pa.us       15518                 :UBC           0 :         aggfinalmodify = defaultfinalmodify;
 2935 tgl@sss.pgh.pa.us       15519         [ -  + ]:CBC         285 :     if (aggmfinalmodify == '0')
 2935 tgl@sss.pgh.pa.us       15520                 :UBC           0 :         aggmfinalmodify = defaultfinalmodify;
                              15521                 :                : 
                              15522                 :                :     /* regproc and regtype output is already sufficiently quoted */
 3302 tgl@sss.pgh.pa.us       15523                 :CBC         285 :     appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                              15524                 :                :                       aggtransfn, aggtranstype);
                              15525                 :                : 
 4363                         15526         [ +  + ]:            285 :     if (strcmp(aggtransspace, "0") != 0)
                              15527                 :                :     {
                              15528                 :              5 :         appendPQExpBuffer(details, ",\n    SSPACE = %s",
                              15529                 :                :                           aggtransspace);
                              15530                 :                :     }
                              15531                 :                : 
 8571                         15532         [ +  + ]:            285 :     if (!PQgetisnull(res, 0, i_agginitval))
                              15533                 :                :     {
 4361 heikki.linnakangas@i    15534                 :            207 :         appendPQExpBufferStr(details, ",\n    INITCOND = ");
 7092 tgl@sss.pgh.pa.us       15535                 :            207 :         appendStringLiteralAH(details, agginitval, fout);
                              15536                 :                :     }
                              15537                 :                : 
 8571                         15538         [ +  + ]:            285 :     if (strcmp(aggfinalfn, "-") != 0)
                              15539                 :                :     {
 8471 peter_e@gmx.net         15540                 :            132 :         appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                              15541                 :                :                           aggfinalfn);
 4205 tgl@sss.pgh.pa.us       15542         [ +  + ]:            132 :         if (aggfinalextra)
                              15543                 :             10 :             appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
 2935                         15544         [ +  + ]:            132 :         if (aggfinalmodify != defaultfinalmodify)
                              15545                 :                :         {
                              15546   [ -  +  -  - ]:             32 :             switch (aggfinalmodify)
                              15547                 :                :             {
 2935 tgl@sss.pgh.pa.us       15548                 :UBC           0 :                 case AGGMODIFY_READ_ONLY:
                              15549                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_ONLY");
                              15550                 :              0 :                     break;
 2716 tgl@sss.pgh.pa.us       15551                 :CBC          32 :                 case AGGMODIFY_SHAREABLE:
                              15552                 :             32 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = SHAREABLE");
 2935                         15553                 :             32 :                     break;
 2935 tgl@sss.pgh.pa.us       15554                 :UBC           0 :                 case AGGMODIFY_READ_WRITE:
                              15555                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_WRITE");
                              15556                 :              0 :                     break;
                              15557                 :              0 :                 default:
 1298                         15558                 :              0 :                     pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
                              15559                 :                :                              agginfo->aggfn.dobj.name);
                              15560                 :                :                     break;
                              15561                 :                :             }
                              15562                 :                :         }
                              15563                 :                :     }
                              15564                 :                : 
 3568 rhaas@postgresql.org    15565         [ -  + ]:CBC         285 :     if (strcmp(aggcombinefn, "-") != 0)
 3427 rhaas@postgresql.org    15566                 :UBC           0 :         appendPQExpBuffer(details, ",\n    COMBINEFUNC = %s", aggcombinefn);
                              15567                 :                : 
 3499 rhaas@postgresql.org    15568         [ -  + ]:CBC         285 :     if (strcmp(aggserialfn, "-") != 0)
 3427 rhaas@postgresql.org    15569                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SERIALFUNC = %s", aggserialfn);
                              15570                 :                : 
 3414 tgl@sss.pgh.pa.us       15571         [ -  + ]:CBC         285 :     if (strcmp(aggdeserialfn, "-") != 0)
 3427 rhaas@postgresql.org    15572                 :UBC           0 :         appendPQExpBuffer(details, ",\n    DESERIALFUNC = %s", aggdeserialfn);
                              15573                 :                : 
 4216 tgl@sss.pgh.pa.us       15574         [ +  + ]:CBC         285 :     if (strcmp(aggmtransfn, "-") != 0)
                              15575                 :                :     {
                              15576                 :             30 :         appendPQExpBuffer(details, ",\n    MSFUNC = %s,\n    MINVFUNC = %s,\n    MSTYPE = %s",
                              15577                 :                :                           aggmtransfn,
                              15578                 :                :                           aggminvtransfn,
                              15579                 :                :                           aggmtranstype);
                              15580                 :                :     }
                              15581                 :                : 
                              15582         [ -  + ]:            285 :     if (strcmp(aggmtransspace, "0") != 0)
                              15583                 :                :     {
 4216 tgl@sss.pgh.pa.us       15584                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MSSPACE = %s",
                              15585                 :                :                           aggmtransspace);
                              15586                 :                :     }
                              15587                 :                : 
 4216 tgl@sss.pgh.pa.us       15588         [ +  + ]:CBC         285 :     if (!PQgetisnull(res, 0, i_aggminitval))
                              15589                 :                :     {
                              15590                 :             10 :         appendPQExpBufferStr(details, ",\n    MINITCOND = ");
                              15591                 :             10 :         appendStringLiteralAH(details, aggminitval, fout);
                              15592                 :                :     }
                              15593                 :                : 
                              15594         [ -  + ]:            285 :     if (strcmp(aggmfinalfn, "-") != 0)
                              15595                 :                :     {
 4216 tgl@sss.pgh.pa.us       15596                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MFINALFUNC = %s",
                              15597                 :                :                           aggmfinalfn);
 4205                         15598         [ #  # ]:              0 :         if (aggmfinalextra)
                              15599                 :              0 :             appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
 2935                         15600         [ #  # ]:              0 :         if (aggmfinalmodify != defaultfinalmodify)
                              15601                 :                :         {
                              15602   [ #  #  #  # ]:              0 :             switch (aggmfinalmodify)
                              15603                 :                :             {
                              15604                 :              0 :                 case AGGMODIFY_READ_ONLY:
                              15605                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_ONLY");
                              15606                 :              0 :                     break;
 2716                         15607                 :              0 :                 case AGGMODIFY_SHAREABLE:
                              15608                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = SHAREABLE");
 2935                         15609                 :              0 :                     break;
                              15610                 :              0 :                 case AGGMODIFY_READ_WRITE:
                              15611                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_WRITE");
                              15612                 :              0 :                     break;
                              15613                 :              0 :                 default:
 1298                         15614                 :              0 :                     pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
                              15615                 :                :                              agginfo->aggfn.dobj.name);
                              15616                 :                :                     break;
                              15617                 :                :             }
                              15618                 :                :         }
                              15619                 :                :     }
                              15620                 :                : 
 1889 peter@eisentraut.org    15621                 :CBC         285 :     aggsortconvop = getFormattedOperatorName(aggsortop);
 4258 sfrost@snowman.net      15622         [ -  + ]:            285 :     if (aggsortconvop)
                              15623                 :                :     {
 7503 tgl@sss.pgh.pa.us       15624                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SORTOP = %s",
                              15625                 :                :                           aggsortconvop);
 4258 sfrost@snowman.net      15626                 :              0 :         free(aggsortconvop);
                              15627                 :                :     }
                              15628                 :                : 
 2935 tgl@sss.pgh.pa.us       15629         [ +  + ]:CBC         285 :     if (aggkind == AGGKIND_HYPOTHETICAL)
 4326                         15630                 :              5 :         appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
                              15631                 :                : 
 1930 peter@eisentraut.org    15632         [ +  + ]:            285 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              15633                 :                :     {
 3477 rhaas@postgresql.org    15634         [ +  - ]:              5 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              15635                 :              5 :             appendPQExpBufferStr(details, ",\n    PARALLEL = safe");
 3477 rhaas@postgresql.org    15636         [ #  # ]:UBC           0 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              15637                 :              0 :             appendPQExpBufferStr(details, ",\n    PARALLEL = restricted");
                              15638         [ #  # ]:              0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
 1298 tgl@sss.pgh.pa.us       15639                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              15640                 :                :                      agginfo->aggfn.dobj.name);
                              15641                 :                :     }
                              15642                 :                : 
 8553 tgl@sss.pgh.pa.us       15643                 :CBC         285 :     appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
 7908                         15644                 :            285 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              15645                 :                :                       aggsig);
                              15646                 :                : 
 2800                         15647         [ +  - ]:            570 :     appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
                              15648                 :            285 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              15649                 :                :                       aggfullsig ? aggfullsig : aggsig, details->data);
                              15650                 :                : 
 4031 alvherre@alvh.no-ip.    15651         [ +  + ]:            285 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15652                 :             49 :         binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
                              15653                 :                :                                         "AGGREGATE", aggsig,
                              15654                 :             49 :                                         agginfo->aggfn.dobj.namespace->dobj.name);
                              15655                 :                : 
 3491 sfrost@snowman.net      15656         [ +  + ]:            285 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15657                 :            268 :         ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
                              15658                 :            268 :                      agginfo->aggfn.dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15659                 :            268 :                      ARCHIVE_OPTS(.tag = aggsig_tag,
                              15660                 :                :                                   .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
                              15661                 :                :                                   .owner = agginfo->aggfn.rolname,
                              15662                 :                :                                   .description = "AGGREGATE",
                              15663                 :                :                                   .section = SECTION_PRE_DATA,
                              15664                 :                :                                   .createStmt = q->data,
                              15665                 :                :                                   .dropStmt = delq->data));
                              15666                 :                : 
                              15667                 :                :     /* Dump Aggregate Comments */
 3491 sfrost@snowman.net      15668         [ +  + ]:            285 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15669                 :             10 :         dumpComment(fout, "AGGREGATE", aggsig,
 3491 sfrost@snowman.net      15670                 :             10 :                     agginfo->aggfn.dobj.namespace->dobj.name,
                              15671                 :             10 :                     agginfo->aggfn.rolname,
                              15672                 :             10 :                     agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              15673                 :                : 
                              15674         [ -  + ]:            285 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       15675                 :UBC           0 :         dumpSecLabel(fout, "AGGREGATE", aggsig,
 3491 sfrost@snowman.net      15676                 :              0 :                      agginfo->aggfn.dobj.namespace->dobj.name,
                              15677                 :              0 :                      agginfo->aggfn.rolname,
 3050 tgl@sss.pgh.pa.us       15678                 :              0 :                      agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              15679                 :                : 
                              15680                 :                :     /*
                              15681                 :                :      * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
                              15682                 :                :      * command look like a function's GRANT; in particular this affects the
                              15683                 :                :      * syntax for zero-argument aggregates and ordered-set aggregates.
                              15684                 :                :      */
 7996 tgl@sss.pgh.pa.us       15685                 :CBC         285 :     free(aggsig);
                              15686                 :                : 
 5012 rhaas@postgresql.org    15687                 :            285 :     aggsig = format_function_signature(fout, &agginfo->aggfn, true);
                              15688                 :                : 
 3491 sfrost@snowman.net      15689         [ +  + ]:            285 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       15690                 :             18 :         dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
                              15691                 :                :                 "FUNCTION", aggsig, NULL,
 3491 sfrost@snowman.net      15692                 :             18 :                 agginfo->aggfn.dobj.namespace->dobj.name,
  574 tgl@sss.pgh.pa.us       15693                 :             18 :                 NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
                              15694                 :                : 
 7996                         15695                 :            285 :     free(aggsig);
 1229 peter@eisentraut.org    15696                 :            285 :     free(aggfullsig);
 7996 tgl@sss.pgh.pa.us       15697                 :            285 :     free(aggsig_tag);
                              15698                 :                : 
 8571                         15699                 :            285 :     PQclear(res);
                              15700                 :                : 
                              15701                 :            285 :     destroyPQExpBuffer(query);
 8851                         15702                 :            285 :     destroyPQExpBuffer(q);
                              15703                 :            285 :     destroyPQExpBuffer(delq);
                              15704                 :            285 :     destroyPQExpBuffer(details);
                              15705                 :                : }
                              15706                 :                : 
                              15707                 :                : /*
                              15708                 :                :  * dumpTSParser
                              15709                 :                :  *    write out a single text search parser
                              15710                 :                :  */
                              15711                 :                : static void
 1720 peter@eisentraut.org    15712                 :             41 : dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
                              15713                 :                : {
 3575 tgl@sss.pgh.pa.us       15714                 :             41 :     DumpOptions *dopt = fout->dopt;
                              15715                 :                :     PQExpBuffer q;
                              15716                 :                :     PQExpBuffer delq;
                              15717                 :                :     char       *qprsname;
                              15718                 :                : 
                              15719                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15720         [ +  + ]:             41 :     if (!dopt->dumpSchema)
 6642 tgl@sss.pgh.pa.us       15721                 :              6 :         return;
                              15722                 :                : 
                              15723                 :             35 :     q = createPQExpBuffer();
                              15724                 :             35 :     delq = createPQExpBuffer();
                              15725                 :                : 
 2800                         15726                 :             35 :     qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
                              15727                 :                : 
 6642                         15728                 :             35 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
 2800                         15729                 :             35 :                       fmtQualifiedDumpable(prsinfo));
                              15730                 :                : 
 6642                         15731                 :             35 :     appendPQExpBuffer(q, "    START = %s,\n",
 5011 rhaas@postgresql.org    15732                 :             35 :                       convertTSFunction(fout, prsinfo->prsstart));
 6642 tgl@sss.pgh.pa.us       15733                 :             35 :     appendPQExpBuffer(q, "    GETTOKEN = %s,\n",
 5011 rhaas@postgresql.org    15734                 :             35 :                       convertTSFunction(fout, prsinfo->prstoken));
 6642 tgl@sss.pgh.pa.us       15735                 :             35 :     appendPQExpBuffer(q, "    END = %s,\n",
 5011 rhaas@postgresql.org    15736                 :             35 :                       convertTSFunction(fout, prsinfo->prsend));
 6642 tgl@sss.pgh.pa.us       15737         [ +  + ]:             35 :     if (prsinfo->prsheadline != InvalidOid)
                              15738                 :              3 :         appendPQExpBuffer(q, "    HEADLINE = %s,\n",
 5011 rhaas@postgresql.org    15739                 :              3 :                           convertTSFunction(fout, prsinfo->prsheadline));
 6642 tgl@sss.pgh.pa.us       15740                 :             35 :     appendPQExpBuffer(q, "    LEXTYPES = %s );\n",
 5011 rhaas@postgresql.org    15741                 :             35 :                       convertTSFunction(fout, prsinfo->prslextype));
                              15742                 :                : 
 2800 tgl@sss.pgh.pa.us       15743                 :             35 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
                              15744                 :             35 :                       fmtQualifiedDumpable(prsinfo));
                              15745                 :                : 
 4031 alvherre@alvh.no-ip.    15746         [ +  + ]:             35 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15747                 :              1 :         binary_upgrade_extension_member(q, &prsinfo->dobj,
                              15748                 :                :                                         "TEXT SEARCH PARSER", qprsname,
                              15749                 :              1 :                                         prsinfo->dobj.namespace->dobj.name);
                              15750                 :                : 
 3491 sfrost@snowman.net      15751         [ +  - ]:             35 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15752                 :             35 :         ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15753                 :             35 :                      ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
                              15754                 :                :                                   .namespace = prsinfo->dobj.namespace->dobj.name,
                              15755                 :                :                                   .description = "TEXT SEARCH PARSER",
                              15756                 :                :                                   .section = SECTION_PRE_DATA,
                              15757                 :                :                                   .createStmt = q->data,
                              15758                 :                :                                   .dropStmt = delq->data));
                              15759                 :                : 
                              15760                 :                :     /* Dump Parser Comments */
 3491 sfrost@snowman.net      15761         [ +  - ]:             35 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15762                 :             35 :         dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
 3157                         15763                 :             35 :                     prsinfo->dobj.namespace->dobj.name, "",
 3491 sfrost@snowman.net      15764                 :             35 :                     prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
                              15765                 :                : 
 6642 tgl@sss.pgh.pa.us       15766                 :             35 :     destroyPQExpBuffer(q);
                              15767                 :             35 :     destroyPQExpBuffer(delq);
 2800                         15768                 :             35 :     free(qprsname);
                              15769                 :                : }
                              15770                 :                : 
                              15771                 :                : /*
                              15772                 :                :  * dumpTSDictionary
                              15773                 :                :  *    write out a single text search dictionary
                              15774                 :                :  */
                              15775                 :                : static void
 1720 peter@eisentraut.org    15776                 :            173 : dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
                              15777                 :                : {
 3575 tgl@sss.pgh.pa.us       15778                 :            173 :     DumpOptions *dopt = fout->dopt;
                              15779                 :                :     PQExpBuffer q;
                              15780                 :                :     PQExpBuffer delq;
                              15781                 :                :     PQExpBuffer query;
                              15782                 :                :     char       *qdictname;
                              15783                 :                :     PGresult   *res;
                              15784                 :                :     char       *nspname;
                              15785                 :                :     char       *tmplname;
                              15786                 :                : 
                              15787                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15788         [ +  + ]:            173 :     if (!dopt->dumpSchema)
 6642 tgl@sss.pgh.pa.us       15789                 :              6 :         return;
                              15790                 :                : 
                              15791                 :            167 :     q = createPQExpBuffer();
                              15792                 :            167 :     delq = createPQExpBuffer();
                              15793                 :            167 :     query = createPQExpBuffer();
                              15794                 :                : 
 2800                         15795                 :            167 :     qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
                              15796                 :                : 
                              15797                 :                :     /* Fetch name and namespace of the dictionary's template */
 6642                         15798                 :            167 :     appendPQExpBuffer(query, "SELECT nspname, tmplname "
                              15799                 :                :                       "FROM pg_ts_template p, pg_namespace n "
                              15800                 :                :                       "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
                              15801                 :            167 :                       dictinfo->dicttemplate);
 5002 rhaas@postgresql.org    15802                 :            167 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6642 tgl@sss.pgh.pa.us       15803                 :            167 :     nspname = PQgetvalue(res, 0, 0);
                              15804                 :            167 :     tmplname = PQgetvalue(res, 0, 1);
                              15805                 :                : 
                              15806                 :            167 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
 2800                         15807                 :            167 :                       fmtQualifiedDumpable(dictinfo));
                              15808                 :                : 
 4361 heikki.linnakangas@i    15809                 :            167 :     appendPQExpBufferStr(q, "    TEMPLATE = ");
 2800 tgl@sss.pgh.pa.us       15810                 :            167 :     appendPQExpBuffer(q, "%s.", fmtId(nspname));
 4361 heikki.linnakangas@i    15811                 :            167 :     appendPQExpBufferStr(q, fmtId(tmplname));
                              15812                 :                : 
 6642 tgl@sss.pgh.pa.us       15813                 :            167 :     PQclear(res);
                              15814                 :                : 
                              15815                 :                :     /* the dictinitoption can be dumped straight into the command */
                              15816         [ +  + ]:            167 :     if (dictinfo->dictinitoption)
 6641                         15817                 :            132 :         appendPQExpBuffer(q, ",\n    %s", dictinfo->dictinitoption);
                              15818                 :                : 
 4361 heikki.linnakangas@i    15819                 :            167 :     appendPQExpBufferStr(q, " );\n");
                              15820                 :                : 
 2800 tgl@sss.pgh.pa.us       15821                 :            167 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
                              15822                 :            167 :                       fmtQualifiedDumpable(dictinfo));
                              15823                 :                : 
 4031 alvherre@alvh.no-ip.    15824         [ +  + ]:            167 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15825                 :             10 :         binary_upgrade_extension_member(q, &dictinfo->dobj,
                              15826                 :                :                                         "TEXT SEARCH DICTIONARY", qdictname,
                              15827                 :             10 :                                         dictinfo->dobj.namespace->dobj.name);
                              15828                 :                : 
 3491 sfrost@snowman.net      15829         [ +  - ]:            167 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15830                 :            167 :         ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15831                 :            167 :                      ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
                              15832                 :                :                                   .namespace = dictinfo->dobj.namespace->dobj.name,
                              15833                 :                :                                   .owner = dictinfo->rolname,
                              15834                 :                :                                   .description = "TEXT SEARCH DICTIONARY",
                              15835                 :                :                                   .section = SECTION_PRE_DATA,
                              15836                 :                :                                   .createStmt = q->data,
                              15837                 :                :                                   .dropStmt = delq->data));
                              15838                 :                : 
                              15839                 :                :     /* Dump Dictionary Comments */
 3491 sfrost@snowman.net      15840         [ +  + ]:            167 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15841                 :            122 :         dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
 3157                         15842                 :            122 :                     dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
 3491 sfrost@snowman.net      15843                 :            122 :                     dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
                              15844                 :                : 
 6642 tgl@sss.pgh.pa.us       15845                 :            167 :     destroyPQExpBuffer(q);
                              15846                 :            167 :     destroyPQExpBuffer(delq);
                              15847                 :            167 :     destroyPQExpBuffer(query);
 2800                         15848                 :            167 :     free(qdictname);
                              15849                 :                : }
                              15850                 :                : 
                              15851                 :                : /*
                              15852                 :                :  * dumpTSTemplate
                              15853                 :                :  *    write out a single text search template
                              15854                 :                :  */
                              15855                 :                : static void
 1720 peter@eisentraut.org    15856                 :             53 : dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
                              15857                 :                : {
 3575 tgl@sss.pgh.pa.us       15858                 :             53 :     DumpOptions *dopt = fout->dopt;
                              15859                 :                :     PQExpBuffer q;
                              15860                 :                :     PQExpBuffer delq;
                              15861                 :                :     char       *qtmplname;
                              15862                 :                : 
                              15863                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15864         [ +  + ]:             53 :     if (!dopt->dumpSchema)
 6642 tgl@sss.pgh.pa.us       15865                 :              6 :         return;
                              15866                 :                : 
                              15867                 :             47 :     q = createPQExpBuffer();
                              15868                 :             47 :     delq = createPQExpBuffer();
                              15869                 :                : 
 2800                         15870                 :             47 :     qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
                              15871                 :                : 
 6642                         15872                 :             47 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
 2800                         15873                 :             47 :                       fmtQualifiedDumpable(tmplinfo));
                              15874                 :                : 
 6642                         15875         [ +  + ]:             47 :     if (tmplinfo->tmplinit != InvalidOid)
                              15876                 :             15 :         appendPQExpBuffer(q, "    INIT = %s,\n",
 5011 rhaas@postgresql.org    15877                 :             15 :                           convertTSFunction(fout, tmplinfo->tmplinit));
 6642 tgl@sss.pgh.pa.us       15878                 :             47 :     appendPQExpBuffer(q, "    LEXIZE = %s );\n",
 5011 rhaas@postgresql.org    15879                 :             47 :                       convertTSFunction(fout, tmplinfo->tmpllexize));
                              15880                 :                : 
 2800 tgl@sss.pgh.pa.us       15881                 :             47 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
                              15882                 :             47 :                       fmtQualifiedDumpable(tmplinfo));
                              15883                 :                : 
 4031 alvherre@alvh.no-ip.    15884         [ +  + ]:             47 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       15885                 :              1 :         binary_upgrade_extension_member(q, &tmplinfo->dobj,
                              15886                 :                :                                         "TEXT SEARCH TEMPLATE", qtmplname,
                              15887                 :              1 :                                         tmplinfo->dobj.namespace->dobj.name);
                              15888                 :                : 
 3491 sfrost@snowman.net      15889         [ +  - ]:             47 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15890                 :             47 :         ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    15891                 :             47 :                      ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
                              15892                 :                :                                   .namespace = tmplinfo->dobj.namespace->dobj.name,
                              15893                 :                :                                   .description = "TEXT SEARCH TEMPLATE",
                              15894                 :                :                                   .section = SECTION_PRE_DATA,
                              15895                 :                :                                   .createStmt = q->data,
                              15896                 :                :                                   .dropStmt = delq->data));
                              15897                 :                : 
                              15898                 :                :     /* Dump Template Comments */
 3491 sfrost@snowman.net      15899         [ +  - ]:             47 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       15900                 :             47 :         dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
 3157                         15901                 :             47 :                     tmplinfo->dobj.namespace->dobj.name, "",
 3491 sfrost@snowman.net      15902                 :             47 :                     tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
                              15903                 :                : 
 6642 tgl@sss.pgh.pa.us       15904                 :             47 :     destroyPQExpBuffer(q);
                              15905                 :             47 :     destroyPQExpBuffer(delq);
 2800                         15906                 :             47 :     free(qtmplname);
                              15907                 :                : }
                              15908                 :                : 
                              15909                 :                : /*
                              15910                 :                :  * dumpTSConfig
                              15911                 :                :  *    write out a single text search configuration
                              15912                 :                :  */
                              15913                 :                : static void
 1720 peter@eisentraut.org    15914                 :            148 : dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
                              15915                 :                : {
 3575 tgl@sss.pgh.pa.us       15916                 :            148 :     DumpOptions *dopt = fout->dopt;
                              15917                 :                :     PQExpBuffer q;
                              15918                 :                :     PQExpBuffer delq;
                              15919                 :                :     PQExpBuffer query;
                              15920                 :                :     char       *qcfgname;
                              15921                 :                :     PGresult   *res;
                              15922                 :                :     char       *nspname;
                              15923                 :                :     char       *prsname;
                              15924                 :                :     int         ntups,
                              15925                 :                :                 i;
                              15926                 :                :     int         i_tokenname;
                              15927                 :                :     int         i_dictname;
                              15928                 :                : 
                              15929                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    15930         [ +  + ]:            148 :     if (!dopt->dumpSchema)
 6642 tgl@sss.pgh.pa.us       15931                 :              6 :         return;
                              15932                 :                : 
                              15933                 :            142 :     q = createPQExpBuffer();
                              15934                 :            142 :     delq = createPQExpBuffer();
                              15935                 :            142 :     query = createPQExpBuffer();
                              15936                 :                : 
 2800                         15937                 :            142 :     qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
                              15938                 :                : 
                              15939                 :                :     /* Fetch name and namespace of the config's parser */
 6642                         15940                 :            142 :     appendPQExpBuffer(query, "SELECT nspname, prsname "
                              15941                 :                :                       "FROM pg_ts_parser p, pg_namespace n "
                              15942                 :                :                       "WHERE p.oid = '%u' AND n.oid = prsnamespace",
                              15943                 :            142 :                       cfginfo->cfgparser);
 5002 rhaas@postgresql.org    15944                 :            142 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6642 tgl@sss.pgh.pa.us       15945                 :            142 :     nspname = PQgetvalue(res, 0, 0);
                              15946                 :            142 :     prsname = PQgetvalue(res, 0, 1);
                              15947                 :                : 
                              15948                 :            142 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
 2800                         15949                 :            142 :                       fmtQualifiedDumpable(cfginfo));
                              15950                 :                : 
                              15951                 :            142 :     appendPQExpBuffer(q, "    PARSER = %s.", fmtId(nspname));
 6642                         15952                 :            142 :     appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
                              15953                 :                : 
                              15954                 :            142 :     PQclear(res);
                              15955                 :                : 
                              15956                 :            142 :     resetPQExpBuffer(query);
                              15957                 :            142 :     appendPQExpBuffer(query,
                              15958                 :                :                       "SELECT\n"
                              15959                 :                :                       "  ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
                              15960                 :                :                       "    WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
                              15961                 :                :                       "  m.mapdict::pg_catalog.regdictionary AS dictname\n"
                              15962                 :                :                       "FROM pg_catalog.pg_ts_config_map AS m\n"
                              15963                 :                :                       "WHERE m.mapcfg = '%u'\n"
                              15964                 :                :                       "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
                              15965                 :            142 :                       cfginfo->cfgparser, cfginfo->dobj.catId.oid);
                              15966                 :                : 
 5011 rhaas@postgresql.org    15967                 :            142 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 6642 tgl@sss.pgh.pa.us       15968                 :            142 :     ntups = PQntuples(res);
                              15969                 :                : 
                              15970                 :            142 :     i_tokenname = PQfnumber(res, "tokenname");
                              15971                 :            142 :     i_dictname = PQfnumber(res, "dictname");
                              15972                 :                : 
                              15973         [ +  + ]:           2975 :     for (i = 0; i < ntups; i++)
                              15974                 :                :     {
 6556 bruce@momjian.us        15975                 :           2833 :         char       *tokenname = PQgetvalue(res, i, i_tokenname);
                              15976                 :           2833 :         char       *dictname = PQgetvalue(res, i, i_dictname);
                              15977                 :                : 
 6642 tgl@sss.pgh.pa.us       15978         [ +  + ]:           2833 :         if (i == 0 ||
 6556 bruce@momjian.us        15979         [ +  + ]:           2691 :             strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
                              15980                 :                :         {
                              15981                 :                :             /* starting a new token type, so start a new command */
 6642 tgl@sss.pgh.pa.us       15982         [ +  + ]:           2698 :             if (i > 0)
 4361 heikki.linnakangas@i    15983                 :           2556 :                 appendPQExpBufferStr(q, ";\n");
 6642 tgl@sss.pgh.pa.us       15984                 :           2698 :             appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
 2800                         15985                 :           2698 :                               fmtQualifiedDumpable(cfginfo));
                              15986                 :                :             /* tokenname needs quoting, dictname does NOT */
 6642                         15987                 :           2698 :             appendPQExpBuffer(q, "    ADD MAPPING FOR %s WITH %s",
                              15988                 :                :                               fmtId(tokenname), dictname);
                              15989                 :                :         }
                              15990                 :                :         else
                              15991                 :            135 :             appendPQExpBuffer(q, ", %s", dictname);
                              15992                 :                :     }
                              15993                 :                : 
                              15994         [ +  - ]:            142 :     if (ntups > 0)
 4361 heikki.linnakangas@i    15995                 :            142 :         appendPQExpBufferStr(q, ";\n");
                              15996                 :                : 
 6642 tgl@sss.pgh.pa.us       15997                 :            142 :     PQclear(res);
                              15998                 :                : 
 2800                         15999                 :            142 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
                              16000                 :            142 :                       fmtQualifiedDumpable(cfginfo));
                              16001                 :                : 
 4031 alvherre@alvh.no-ip.    16002         [ +  + ]:            142 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       16003                 :              5 :         binary_upgrade_extension_member(q, &cfginfo->dobj,
                              16004                 :                :                                         "TEXT SEARCH CONFIGURATION", qcfgname,
                              16005                 :              5 :                                         cfginfo->dobj.namespace->dobj.name);
                              16006                 :                : 
 3491 sfrost@snowman.net      16007         [ +  - ]:            142 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16008                 :            142 :         ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    16009                 :            142 :                      ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
                              16010                 :                :                                   .namespace = cfginfo->dobj.namespace->dobj.name,
                              16011                 :                :                                   .owner = cfginfo->rolname,
                              16012                 :                :                                   .description = "TEXT SEARCH CONFIGURATION",
                              16013                 :                :                                   .section = SECTION_PRE_DATA,
                              16014                 :                :                                   .createStmt = q->data,
                              16015                 :                :                                   .dropStmt = delq->data));
                              16016                 :                : 
                              16017                 :                :     /* Dump Configuration Comments */
 3491 sfrost@snowman.net      16018         [ +  + ]:            142 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       16019                 :            122 :         dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
 3157                         16020                 :            122 :                     cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
 3491 sfrost@snowman.net      16021                 :            122 :                     cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
                              16022                 :                : 
 6642 tgl@sss.pgh.pa.us       16023                 :            142 :     destroyPQExpBuffer(q);
                              16024                 :            142 :     destroyPQExpBuffer(delq);
                              16025                 :            142 :     destroyPQExpBuffer(query);
 2800                         16026                 :            142 :     free(qcfgname);
                              16027                 :                : }
                              16028                 :                : 
                              16029                 :                : /*
                              16030                 :                :  * dumpForeignDataWrapper
                              16031                 :                :  *    write out a single foreign-data wrapper definition
                              16032                 :                :  */
                              16033                 :                : static void
 1720 peter@eisentraut.org    16034                 :             52 : dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
                              16035                 :                : {
 3575 tgl@sss.pgh.pa.us       16036                 :             52 :     DumpOptions *dopt = fout->dopt;
                              16037                 :                :     PQExpBuffer q;
                              16038                 :                :     PQExpBuffer delq;
                              16039                 :                :     char       *qfdwname;
                              16040                 :                : 
                              16041                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    16042         [ +  + ]:             52 :     if (!dopt->dumpSchema)
 6156 peter_e@gmx.net         16043                 :              7 :         return;
                              16044                 :                : 
                              16045                 :             45 :     q = createPQExpBuffer();
                              16046                 :             45 :     delq = createPQExpBuffer();
                              16047                 :                : 
 5085 bruce@momjian.us        16048                 :             45 :     qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
                              16049                 :                : 
 6089 peter_e@gmx.net         16050                 :             45 :     appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
                              16051                 :                :                       qfdwname);
                              16052                 :                : 
 5364 tgl@sss.pgh.pa.us       16053         [ -  + ]:             45 :     if (strcmp(fdwinfo->fdwhandler, "-") != 0)
 5364 tgl@sss.pgh.pa.us       16054                 :UBC           0 :         appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
                              16055                 :                : 
 5364 tgl@sss.pgh.pa.us       16056         [ -  + ]:CBC          45 :     if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
 5364 tgl@sss.pgh.pa.us       16057                 :UBC           0 :         appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
                              16058                 :                : 
 5364 tgl@sss.pgh.pa.us       16059         [ -  + ]:CBC          45 :     if (strlen(fdwinfo->fdwoptions) > 0)
 5044 peter_e@gmx.net         16060                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", fdwinfo->fdwoptions);
                              16061                 :                : 
 4361 heikki.linnakangas@i    16062                 :CBC          45 :     appendPQExpBufferStr(q, ";\n");
                              16063                 :                : 
 6156 peter_e@gmx.net         16064                 :             45 :     appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                              16065                 :                :                       qfdwname);
                              16066                 :                : 
 4031 alvherre@alvh.no-ip.    16067         [ +  + ]:             45 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       16068                 :              2 :         binary_upgrade_extension_member(q, &fdwinfo->dobj,
                              16069                 :                :                                         "FOREIGN DATA WRAPPER", qfdwname,
                              16070                 :                :                                         NULL);
                              16071                 :                : 
 3491 sfrost@snowman.net      16072         [ +  - ]:             45 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16073                 :             45 :         ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    16074                 :             45 :                      ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
                              16075                 :                :                                   .owner = fdwinfo->rolname,
                              16076                 :                :                                   .description = "FOREIGN DATA WRAPPER",
                              16077                 :                :                                   .section = SECTION_PRE_DATA,
                              16078                 :                :                                   .createStmt = q->data,
                              16079                 :                :                                   .dropStmt = delq->data));
                              16080                 :                : 
                              16081                 :                :     /* Dump Foreign Data Wrapper Comments */
 2835 tgl@sss.pgh.pa.us       16082         [ -  + ]:             45 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       16083                 :UBC           0 :         dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
 2835                         16084                 :              0 :                     NULL, fdwinfo->rolname,
                              16085                 :              0 :                     fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
                              16086                 :                : 
                              16087                 :                :     /* Handle the ACL */
 3491 sfrost@snowman.net      16088         [ +  + ]:CBC          45 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       16089                 :             31 :         dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
                              16090                 :                :                 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
 1421                         16091                 :             31 :                 NULL, fdwinfo->rolname, &fdwinfo->dacl);
                              16092                 :                : 
 5374                         16093                 :             45 :     free(qfdwname);
                              16094                 :                : 
 6156 peter_e@gmx.net         16095                 :             45 :     destroyPQExpBuffer(q);
                              16096                 :             45 :     destroyPQExpBuffer(delq);
                              16097                 :                : }
                              16098                 :                : 
                              16099                 :                : /*
                              16100                 :                :  * dumpForeignServer
                              16101                 :                :  *    write out a foreign server definition
                              16102                 :                :  */
                              16103                 :                : static void
 1720 peter@eisentraut.org    16104                 :             56 : dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
                              16105                 :                : {
 3575 tgl@sss.pgh.pa.us       16106                 :             56 :     DumpOptions *dopt = fout->dopt;
                              16107                 :                :     PQExpBuffer q;
                              16108                 :                :     PQExpBuffer delq;
                              16109                 :                :     PQExpBuffer query;
                              16110                 :                :     PGresult   *res;
                              16111                 :                :     char       *qsrvname;
                              16112                 :                :     char       *fdwname;
                              16113                 :                : 
                              16114                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    16115         [ +  + ]:             56 :     if (!dopt->dumpSchema)
 6156 peter_e@gmx.net         16116                 :              9 :         return;
                              16117                 :                : 
                              16118                 :             47 :     q = createPQExpBuffer();
                              16119                 :             47 :     delq = createPQExpBuffer();
                              16120                 :             47 :     query = createPQExpBuffer();
                              16121                 :                : 
 5085 bruce@momjian.us        16122                 :             47 :     qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
                              16123                 :                : 
                              16124                 :                :     /* look up the foreign-data wrapper */
 6156 peter_e@gmx.net         16125                 :             47 :     appendPQExpBuffer(query, "SELECT fdwname "
                              16126                 :                :                       "FROM pg_foreign_data_wrapper w "
                              16127                 :                :                       "WHERE w.oid = '%u'",
                              16128                 :             47 :                       srvinfo->srvfdw);
 5002 rhaas@postgresql.org    16129                 :             47 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6156 peter_e@gmx.net         16130                 :             47 :     fdwname = PQgetvalue(res, 0, 0);
                              16131                 :                : 
 5374 tgl@sss.pgh.pa.us       16132                 :             47 :     appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
 6156 peter_e@gmx.net         16133   [ +  -  -  + ]:             47 :     if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
                              16134                 :                :     {
 4361 heikki.linnakangas@i    16135                 :UBC           0 :         appendPQExpBufferStr(q, " TYPE ");
 6046                         16136                 :              0 :         appendStringLiteralAH(q, srvinfo->srvtype, fout);
                              16137                 :                :     }
 6156 peter_e@gmx.net         16138   [ +  -  -  + ]:CBC          47 :     if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
                              16139                 :                :     {
 4361 heikki.linnakangas@i    16140                 :UBC           0 :         appendPQExpBufferStr(q, " VERSION ");
 6046                         16141                 :              0 :         appendStringLiteralAH(q, srvinfo->srvversion, fout);
                              16142                 :                :     }
                              16143                 :                : 
 4361 heikki.linnakangas@i    16144                 :CBC          47 :     appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
                              16145                 :             47 :     appendPQExpBufferStr(q, fmtId(fdwname));
                              16146                 :                : 
 6156 peter_e@gmx.net         16147   [ +  -  -  + ]:             47 :     if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
 5044 peter_e@gmx.net         16148                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", srvinfo->srvoptions);
                              16149                 :                : 
 4361 heikki.linnakangas@i    16150                 :CBC          47 :     appendPQExpBufferStr(q, ";\n");
                              16151                 :                : 
 6156 peter_e@gmx.net         16152                 :             47 :     appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                              16153                 :                :                       qsrvname);
                              16154                 :                : 
 4031 alvherre@alvh.no-ip.    16155         [ +  + ]:             47 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       16156                 :              2 :         binary_upgrade_extension_member(q, &srvinfo->dobj,
                              16157                 :                :                                         "SERVER", qsrvname, NULL);
                              16158                 :                : 
 3491 sfrost@snowman.net      16159         [ +  - ]:             47 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16160                 :             47 :         ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    16161                 :             47 :                      ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
                              16162                 :                :                                   .owner = srvinfo->rolname,
                              16163                 :                :                                   .description = "SERVER",
                              16164                 :                :                                   .section = SECTION_PRE_DATA,
                              16165                 :                :                                   .createStmt = q->data,
                              16166                 :                :                                   .dropStmt = delq->data));
                              16167                 :                : 
                              16168                 :                :     /* Dump Foreign Server Comments */
 2835 tgl@sss.pgh.pa.us       16169         [ -  + ]:             47 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       16170                 :UBC           0 :         dumpComment(fout, "SERVER", qsrvname,
 2835                         16171                 :              0 :                     NULL, srvinfo->rolname,
                              16172                 :              0 :                     srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
                              16173                 :                : 
                              16174                 :                :     /* Handle the ACL */
 3491 sfrost@snowman.net      16175         [ +  + ]:CBC          47 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1934 tgl@sss.pgh.pa.us       16176                 :             31 :         dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
                              16177                 :                :                 "FOREIGN SERVER", qsrvname, NULL, NULL,
 1421                         16178                 :             31 :                 NULL, srvinfo->rolname, &srvinfo->dacl);
                              16179                 :                : 
                              16180                 :                :     /* Dump user mappings */
 3491 sfrost@snowman.net      16181         [ +  - ]:             47 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
                              16182                 :             47 :         dumpUserMappings(fout,
                              16183                 :             47 :                          srvinfo->dobj.name, NULL,
                              16184                 :             47 :                          srvinfo->rolname,
                              16185                 :             47 :                          srvinfo->dobj.catId, srvinfo->dobj.dumpId);
                              16186                 :                : 
 1464 tgl@sss.pgh.pa.us       16187                 :             47 :     PQclear(res);
                              16188                 :                : 
 5374                         16189                 :             47 :     free(qsrvname);
                              16190                 :                : 
 6156 peter_e@gmx.net         16191                 :             47 :     destroyPQExpBuffer(q);
                              16192                 :             47 :     destroyPQExpBuffer(delq);
 3486 tgl@sss.pgh.pa.us       16193                 :             47 :     destroyPQExpBuffer(query);
                              16194                 :                : }
                              16195                 :                : 
                              16196                 :                : /*
                              16197                 :                :  * dumpUserMappings
                              16198                 :                :  *
                              16199                 :                :  * This routine is used to dump any user mappings associated with the
                              16200                 :                :  * server handed to this routine. Should be called after ArchiveEntry()
                              16201                 :                :  * for the server.
                              16202                 :                :  */
                              16203                 :                : static void
 5584                         16204                 :             47 : dumpUserMappings(Archive *fout,
                              16205                 :                :                  const char *servername, const char *namespace,
                              16206                 :                :                  const char *owner,
                              16207                 :                :                  CatalogId catalogId, DumpId dumpId)
                              16208                 :                : {
                              16209                 :                :     PQExpBuffer q;
                              16210                 :                :     PQExpBuffer delq;
                              16211                 :                :     PQExpBuffer query;
                              16212                 :                :     PQExpBuffer tag;
                              16213                 :                :     PGresult   *res;
                              16214                 :                :     int         ntups;
                              16215                 :                :     int         i_usename;
                              16216                 :                :     int         i_umoptions;
                              16217                 :                :     int         i;
                              16218                 :                : 
 6156 peter_e@gmx.net         16219                 :             47 :     q = createPQExpBuffer();
                              16220                 :             47 :     tag = createPQExpBuffer();
                              16221                 :             47 :     delq = createPQExpBuffer();
                              16222                 :             47 :     query = createPQExpBuffer();
                              16223                 :                : 
                              16224                 :                :     /*
                              16225                 :                :      * We read from the publicly accessible view pg_user_mappings, so as not
                              16226                 :                :      * to fail if run by a non-superuser.  Note that the view will show
                              16227                 :                :      * umoptions as null if the user hasn't got privileges for the associated
                              16228                 :                :      * server; this means that pg_dump will dump such a mapping, but with no
                              16229                 :                :      * OPTIONS clause.  A possible alternative is to skip such mappings
                              16230                 :                :      * altogether, but it's not clear that that's an improvement.
                              16231                 :                :      */
                              16232                 :             47 :     appendPQExpBuffer(query,
                              16233                 :                :                       "SELECT usename, "
                              16234                 :                :                       "array_to_string(ARRAY("
                              16235                 :                :                       "SELECT quote_ident(option_name) || ' ' || "
                              16236                 :                :                       "quote_literal(option_value) "
                              16237                 :                :                       "FROM pg_options_to_table(umoptions) "
                              16238                 :                :                       "ORDER BY option_name"
                              16239                 :                :                       "), E',\n    ') AS umoptions "
                              16240                 :                :                       "FROM pg_user_mappings "
                              16241                 :                :                       "WHERE srvid = '%u' "
                              16242                 :                :                       "ORDER BY usename",
                              16243                 :                :                       catalogId.oid);
                              16244                 :                : 
 5011 rhaas@postgresql.org    16245                 :             47 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16246                 :                : 
 6156 peter_e@gmx.net         16247                 :             47 :     ntups = PQntuples(res);
 5584 tgl@sss.pgh.pa.us       16248                 :             47 :     i_usename = PQfnumber(res, "usename");
 6156 peter_e@gmx.net         16249                 :             47 :     i_umoptions = PQfnumber(res, "umoptions");
                              16250                 :                : 
                              16251         [ +  + ]:             78 :     for (i = 0; i < ntups; i++)
                              16252                 :                :     {
                              16253                 :                :         char       *usename;
                              16254                 :                :         char       *umoptions;
                              16255                 :                : 
 5584 tgl@sss.pgh.pa.us       16256                 :             31 :         usename = PQgetvalue(res, i, i_usename);
 6156 peter_e@gmx.net         16257                 :             31 :         umoptions = PQgetvalue(res, i, i_umoptions);
                              16258                 :                : 
                              16259                 :             31 :         resetPQExpBuffer(q);
 5584 tgl@sss.pgh.pa.us       16260                 :             31 :         appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
 6156 peter_e@gmx.net         16261                 :             31 :         appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
                              16262                 :                : 
                              16263   [ +  -  -  + ]:             31 :         if (umoptions && strlen(umoptions) > 0)
 5044 peter_e@gmx.net         16264                 :UBC           0 :             appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", umoptions);
                              16265                 :                : 
 4361 heikki.linnakangas@i    16266                 :CBC          31 :         appendPQExpBufferStr(q, ";\n");
                              16267                 :                : 
 6156 peter_e@gmx.net         16268                 :             31 :         resetPQExpBuffer(delq);
 5584 tgl@sss.pgh.pa.us       16269                 :             31 :         appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
                              16270                 :             31 :         appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
                              16271                 :                : 
 6156 peter_e@gmx.net         16272                 :             31 :         resetPQExpBuffer(tag);
 5584 tgl@sss.pgh.pa.us       16273                 :             31 :         appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
                              16274                 :                :                           usename, servername);
                              16275                 :                : 
 6156 peter_e@gmx.net         16276                 :             31 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    16277                 :             31 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16278                 :                :                                   .namespace = namespace,
                              16279                 :                :                                   .owner = owner,
                              16280                 :                :                                   .description = "USER MAPPING",
                              16281                 :                :                                   .section = SECTION_PRE_DATA,
                              16282                 :                :                                   .createStmt = q->data,
                              16283                 :                :                                   .dropStmt = delq->data));
                              16284                 :                :     }
                              16285                 :                : 
 6156 peter_e@gmx.net         16286                 :             47 :     PQclear(res);
                              16287                 :                : 
                              16288                 :             47 :     destroyPQExpBuffer(query);
                              16289                 :             47 :     destroyPQExpBuffer(delq);
 4258 sfrost@snowman.net      16290                 :             47 :     destroyPQExpBuffer(tag);
 6156 peter_e@gmx.net         16291                 :             47 :     destroyPQExpBuffer(q);
                              16292                 :             47 : }
                              16293                 :                : 
                              16294                 :                : /*
                              16295                 :                :  * Write out default privileges information
                              16296                 :                :  */
                              16297                 :                : static void
 1720 peter@eisentraut.org    16298                 :            160 : dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
                              16299                 :                : {
 3575 tgl@sss.pgh.pa.us       16300                 :            160 :     DumpOptions *dopt = fout->dopt;
                              16301                 :                :     PQExpBuffer q;
                              16302                 :                :     PQExpBuffer tag;
                              16303                 :                :     const char *type;
                              16304                 :                : 
                              16305                 :                :     /* Do nothing if not dumping schema, or if we're skipping ACLs */
  336 nathan@postgresql.or    16306   [ +  +  +  + ]:            160 :     if (!dopt->dumpSchema || dopt->aclsSkip)
 5866 tgl@sss.pgh.pa.us       16307                 :             28 :         return;
                              16308                 :                : 
                              16309                 :            132 :     q = createPQExpBuffer();
                              16310                 :            132 :     tag = createPQExpBuffer();
                              16311                 :                : 
                              16312   [ +  -  +  +  :            132 :     switch (daclinfo->defaclobjtype)
                                           -  -  - ]
                              16313                 :                :     {
                              16314                 :             61 :         case DEFACLOBJ_RELATION:
 5859                         16315                 :             61 :             type = "TABLES";
 5866                         16316                 :             61 :             break;
 5866 tgl@sss.pgh.pa.us       16317                 :UBC           0 :         case DEFACLOBJ_SEQUENCE:
 5859                         16318                 :              0 :             type = "SEQUENCES";
 5866                         16319                 :              0 :             break;
 5866 tgl@sss.pgh.pa.us       16320                 :CBC          61 :         case DEFACLOBJ_FUNCTION:
 5859                         16321                 :             61 :             type = "FUNCTIONS";
 5866                         16322                 :             61 :             break;
 4705                         16323                 :             10 :         case DEFACLOBJ_TYPE:
                              16324                 :             10 :             type = "TYPES";
                              16325                 :             10 :             break;
 3135 teodor@sigaev.ru        16326                 :UBC           0 :         case DEFACLOBJ_NAMESPACE:
                              16327                 :              0 :             type = "SCHEMAS";
                              16328                 :              0 :             break;
  206 fujii@postgresql.org    16329                 :              0 :         case DEFACLOBJ_LARGEOBJECT:
                              16330                 :              0 :             type = "LARGE OBJECTS";
                              16331                 :              0 :             break;
 5866 tgl@sss.pgh.pa.us       16332                 :              0 :         default:
                              16333                 :                :             /* shouldn't get here */
 1298                         16334                 :              0 :             pg_fatal("unrecognized object type in default privileges: %d",
                              16335                 :                :                      (int) daclinfo->defaclobjtype);
                              16336                 :                :             type = "";            /* keep compiler quiet */
                              16337                 :                :     }
                              16338                 :                : 
 5859 tgl@sss.pgh.pa.us       16339                 :CBC         132 :     appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
                              16340                 :                : 
                              16341                 :                :     /* build the actual command(s) for this tuple */
 5866                         16342         [ -  + ]:            132 :     if (!buildDefaultACLCommands(type,
                              16343                 :            132 :                                  daclinfo->dobj.namespace != NULL ?
                              16344                 :             62 :                                  daclinfo->dobj.namespace->dobj.name : NULL,
 1421                         16345                 :            132 :                                  daclinfo->dacl.acl,
                              16346                 :            132 :                                  daclinfo->dacl.acldefault,
 5866                         16347         [ +  + ]:            132 :                                  daclinfo->defaclrole,
                              16348                 :                :                                  fout->remoteVersion,
                              16349                 :                :                                  q))
 1298 tgl@sss.pgh.pa.us       16350                 :UBC           0 :         pg_fatal("could not parse default ACL list (%s)",
                              16351                 :                :                  daclinfo->dacl.acl);
                              16352                 :                : 
 3491 sfrost@snowman.net      16353         [ +  - ]:CBC         132 :     if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              16354                 :            132 :         ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    16355         [ +  + ]:            132 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16356                 :                :                                   .namespace = daclinfo->dobj.namespace ?
                              16357                 :                :                                   daclinfo->dobj.namespace->dobj.name : NULL,
                              16358                 :                :                                   .owner = daclinfo->defaclrole,
                              16359                 :                :                                   .description = "DEFAULT ACL",
                              16360                 :                :                                   .section = SECTION_POST_DATA,
                              16361                 :                :                                   .createStmt = q->data));
                              16362                 :                : 
 5866 tgl@sss.pgh.pa.us       16363                 :            132 :     destroyPQExpBuffer(tag);
                              16364                 :            132 :     destroyPQExpBuffer(q);
                              16365                 :                : }
                              16366                 :                : 
                              16367                 :                : /*----------
                              16368                 :                :  * Write out grant/revoke information
                              16369                 :                :  *
                              16370                 :                :  * 'objDumpId' is the dump ID of the underlying object.
                              16371                 :                :  * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
                              16372                 :                :  *      or InvalidDumpId if there is no need for a second dependency.
                              16373                 :                :  * 'type' must be one of
                              16374                 :                :  *      TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
                              16375                 :                :  *      FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
                              16376                 :                :  * 'name' is the formatted name of the object.  Must be quoted etc. already.
                              16377                 :                :  * 'subname' is the formatted name of the sub-object, if any.  Must be quoted.
                              16378                 :                :  *      (Currently we assume that subname is only provided for table columns.)
                              16379                 :                :  * 'nspname' is the namespace the object is in (NULL if none).
                              16380                 :                :  * 'tag' is the tag to use for the ACL TOC entry; typically, this is NULL
                              16381                 :                :  *      to use the default for the object type.
                              16382                 :                :  * 'owner' is the owner, NULL if there is no owner (for languages).
                              16383                 :                :  * 'dacl' is the DumpableAcl struct for the object.
                              16384                 :                :  *
                              16385                 :                :  * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
                              16386                 :                :  * no ACL entry was created.
                              16387                 :                :  *----------
                              16388                 :                :  */
                              16389                 :                : static DumpId
 1934                         16390                 :          29180 : dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
                              16391                 :                :         const char *type, const char *name, const char *subname,
                              16392                 :                :         const char *nspname, const char *tag, const char *owner,
                              16393                 :                :         const DumpableAcl *dacl)
                              16394                 :                : {
                              16395                 :          29180 :     DumpId      aclDumpId = InvalidDumpId;
 3575                         16396                 :          29180 :     DumpOptions *dopt = fout->dopt;
 1421                         16397                 :          29180 :     const char *acls = dacl->acl;
                              16398                 :          29180 :     const char *acldefault = dacl->acldefault;
                              16399                 :          29180 :     char        privtype = dacl->privtype;
                              16400                 :          29180 :     const char *initprivs = dacl->initprivs;
                              16401                 :                :     const char *baseacls;
                              16402                 :                :     PQExpBuffer sql;
                              16403                 :                : 
                              16404                 :                :     /* Do nothing if ACL dump is not enabled */
 4031 alvherre@alvh.no-ip.    16405         [ +  + ]:          29180 :     if (dopt->aclsSkip)
 1934 tgl@sss.pgh.pa.us       16406                 :            326 :         return InvalidDumpId;
                              16407                 :                : 
                              16408                 :                :     /* --data-only skips ACLs *except* large object ACLs */
  336 nathan@postgresql.or    16409   [ +  +  -  + ]:          28854 :     if (!dopt->dumpSchema && strcmp(type, "LARGE OBJECT") != 0)
 1934 tgl@sss.pgh.pa.us       16410                 :UBC           0 :         return InvalidDumpId;
                              16411                 :                : 
 8575 tgl@sss.pgh.pa.us       16412                 :CBC       28854 :     sql = createPQExpBuffer();
                              16413                 :                : 
                              16414                 :                :     /*
                              16415                 :                :      * In binary upgrade mode, we don't run an extension's script but instead
                              16416                 :                :      * dump out the objects independently and then recreate them.  To preserve
                              16417                 :                :      * any initial privileges which were set on extension objects, we need to
                              16418                 :                :      * compute the set of GRANT and REVOKE commands necessary to get from the
                              16419                 :                :      * default privileges of an object to its initial privileges as recorded
                              16420                 :                :      * in pg_init_privs.
                              16421                 :                :      *
                              16422                 :                :      * At restore time, we apply these commands after having called
                              16423                 :                :      * binary_upgrade_set_record_init_privs(true).  That tells the backend to
                              16424                 :                :      * copy the results into pg_init_privs.  This is how we preserve the
                              16425                 :                :      * contents of that catalog across binary upgrades.
                              16426                 :                :      */
 1421                         16427   [ +  +  +  +  :          28854 :     if (dopt->binary_upgrade && privtype == 'e' &&
                                              +  - ]
                              16428         [ +  - ]:             13 :         initprivs && *initprivs != '\0')
                              16429                 :                :     {
 2307 drowley@postgresql.o    16430                 :             13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
 2800 tgl@sss.pgh.pa.us       16431         [ -  + ]:             13 :         if (!buildACLCommands(name, subname, nspname, type,
                              16432                 :                :                               initprivs, acldefault, owner,
                              16433                 :                :                               "", fout->remoteVersion, sql))
 1298 tgl@sss.pgh.pa.us       16434                 :UBC           0 :             pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              16435                 :                :                      initprivs, acldefault, name, type);
 2307 drowley@postgresql.o    16436                 :CBC          13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
                              16437                 :                :     }
                              16438                 :                : 
                              16439                 :                :     /*
                              16440                 :                :      * Now figure the GRANT and REVOKE commands needed to get to the object's
                              16441                 :                :      * actual current ACL, starting from the initprivs if given, else from the
                              16442                 :                :      * object-type-specific default.  Also, while buildACLCommands will assume
                              16443                 :                :      * that a NULL/empty acls string means it needn't do anything, what that
                              16444                 :                :      * actually represents is the object-type-specific default; so we need to
                              16445                 :                :      * substitute the acldefault string to get the right results in that case.
                              16446                 :                :      */
 1421 tgl@sss.pgh.pa.us       16447   [ +  +  +  + ]:          28854 :     if (initprivs && *initprivs != '\0')
                              16448                 :                :     {
                              16449                 :          27126 :         baseacls = initprivs;
                              16450   [ +  -  +  + ]:          27126 :         if (acls == NULL || *acls == '\0')
                              16451                 :             17 :             acls = acldefault;
                              16452                 :                :     }
                              16453                 :                :     else
                              16454                 :           1728 :         baseacls = acldefault;
                              16455                 :                : 
 2800                         16456         [ -  + ]:          28854 :     if (!buildACLCommands(name, subname, nspname, type,
                              16457                 :                :                           acls, baseacls, owner,
                              16458                 :                :                           "", fout->remoteVersion, sql))
 1298 tgl@sss.pgh.pa.us       16459                 :UBC           0 :         pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              16460                 :                :                  acls, baseacls, name, type);
                              16461                 :                : 
 8186 tgl@sss.pgh.pa.us       16462         [ +  + ]:CBC       28854 :     if (sql->len > 0)
                              16463                 :                :     {
  574                         16464                 :           1784 :         PQExpBuffer tagbuf = createPQExpBuffer();
                              16465                 :                :         DumpId      aclDeps[2];
 1934                         16466                 :           1784 :         int         nDeps = 0;
                              16467                 :                : 
  574                         16468         [ -  + ]:           1784 :         if (tag)
  574 tgl@sss.pgh.pa.us       16469                 :UBC           0 :             appendPQExpBufferStr(tagbuf, tag);
  574 tgl@sss.pgh.pa.us       16470         [ +  + ]:CBC        1784 :         else if (subname)
                              16471                 :           1047 :             appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
                              16472                 :                :         else
                              16473                 :            737 :             appendPQExpBuffer(tagbuf, "%s %s", type, name);
                              16474                 :                : 
 1934                         16475                 :           1784 :         aclDeps[nDeps++] = objDumpId;
                              16476         [ +  + ]:           1784 :         if (altDumpId != InvalidDumpId)
                              16477                 :            963 :             aclDeps[nDeps++] = altDumpId;
                              16478                 :                : 
                              16479                 :           1784 :         aclDumpId = createDumpId();
                              16480                 :                : 
                              16481                 :           1784 :         ArchiveEntry(fout, nilCatalogId, aclDumpId,
  574                         16482                 :           1784 :                      ARCHIVE_OPTS(.tag = tagbuf->data,
                              16483                 :                :                                   .namespace = nspname,
                              16484                 :                :                                   .owner = owner,
                              16485                 :                :                                   .description = "ACL",
                              16486                 :                :                                   .section = SECTION_NONE,
                              16487                 :                :                                   .createStmt = sql->data,
                              16488                 :                :                                   .deps = aclDeps,
                              16489                 :                :                                   .nDeps = nDeps));
                              16490                 :                : 
                              16491                 :           1784 :         destroyPQExpBuffer(tagbuf);
                              16492                 :                :     }
                              16493                 :                : 
 8575                         16494                 :          28854 :     destroyPQExpBuffer(sql);
                              16495                 :                : 
 1934                         16496                 :          28854 :     return aclDumpId;
                              16497                 :                : }
                              16498                 :                : 
                              16499                 :                : /*
                              16500                 :                :  * dumpSecLabel
                              16501                 :                :  *
                              16502                 :                :  * This routine is used to dump any security labels associated with the
                              16503                 :                :  * object handed to this routine. The routine takes the object type
                              16504                 :                :  * and object name (ready to print, except for schema decoration), plus
                              16505                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              16506                 :                :  * plus catalog ID and subid which are the lookup key for pg_seclabel,
                              16507                 :                :  * plus the dump ID for the object (for setting a dependency).
                              16508                 :                :  * If a matching pg_seclabel entry is found, it is dumped.
                              16509                 :                :  *
                              16510                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              16511                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              16512                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              16513                 :                :  * ordering of the label in the dump file, because this routine is called
                              16514                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              16515                 :                :  * calling ArchiveEntry() for the specified object.
                              16516                 :                :  */
                              16517                 :                : static void
 2800 tgl@sss.pgh.pa.us       16518                 :GBC          10 : dumpSecLabel(Archive *fout, const char *type, const char *name,
                              16519                 :                :              const char *namespace, const char *owner,
                              16520                 :                :              CatalogId catalogId, int subid, DumpId dumpId)
                              16521                 :                : {
 3575                         16522                 :             10 :     DumpOptions *dopt = fout->dopt;
                              16523                 :                :     SecLabelItem *labels;
                              16524                 :                :     int         nlabels;
                              16525                 :                :     int         i;
                              16526                 :                :     PQExpBuffer query;
                              16527                 :                : 
                              16528                 :                :     /* do nothing, if --no-security-labels is supplied */
 4031 alvherre@alvh.no-ip.    16529         [ -  + ]:             10 :     if (dopt->no_security_labels)
 5509 rhaas@postgresql.org    16530                 :UBC           0 :         return;
                              16531                 :                : 
                              16532                 :                :     /*
                              16533                 :                :      * Security labels are schema not data ... except large object labels are
                              16534                 :                :      * data
                              16535                 :                :      */
 2800 tgl@sss.pgh.pa.us       16536         [ -  + ]:GBC          10 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              16537                 :                :     {
  336 nathan@postgresql.or    16538         [ #  # ]:UBC           0 :         if (!dopt->dumpSchema)
 5509 rhaas@postgresql.org    16539                 :              0 :             return;
                              16540                 :                :     }
                              16541                 :                :     else
                              16542                 :                :     {
                              16543                 :                :         /* We do dump large object security labels in binary-upgrade mode */
  336 nathan@postgresql.or    16544   [ +  -  -  + ]:GBC          10 :         if (!dopt->dumpData && !dopt->binary_upgrade)
 5509 rhaas@postgresql.org    16545                 :UBC           0 :             return;
                              16546                 :                :     }
                              16547                 :                : 
                              16548                 :                :     /* Search for security labels associated with catalogId, using table */
 1397 tgl@sss.pgh.pa.us       16549                 :GBC          10 :     nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
                              16550                 :                : 
 5509 rhaas@postgresql.org    16551                 :             10 :     query = createPQExpBuffer();
                              16552                 :                : 
                              16553         [ +  + ]:             15 :     for (i = 0; i < nlabels; i++)
                              16554                 :                :     {
                              16555                 :                :         /*
                              16556                 :                :          * Ignore label entries for which the subid doesn't match.
                              16557                 :                :          */
                              16558         [ -  + ]:              5 :         if (labels[i].objsubid != subid)
 5509 rhaas@postgresql.org    16559                 :UBC           0 :             continue;
                              16560                 :                : 
 5509 rhaas@postgresql.org    16561                 :GBC           5 :         appendPQExpBuffer(query,
                              16562                 :                :                           "SECURITY LABEL FOR %s ON %s ",
 2800 tgl@sss.pgh.pa.us       16563                 :              5 :                           fmtId(labels[i].provider), type);
                              16564   [ -  +  -  - ]:              5 :         if (namespace && *namespace)
 2800 tgl@sss.pgh.pa.us       16565                 :UBC           0 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
 2800 tgl@sss.pgh.pa.us       16566                 :GBC           5 :         appendPQExpBuffer(query, "%s IS ", name);
 5509 rhaas@postgresql.org    16567                 :              5 :         appendStringLiteralAH(query, labels[i].label, fout);
 4361 heikki.linnakangas@i    16568                 :              5 :         appendPQExpBufferStr(query, ";\n");
                              16569                 :                :     }
                              16570                 :                : 
 5509 rhaas@postgresql.org    16571         [ +  + ]:             10 :     if (query->len > 0)
                              16572                 :                :     {
 2800 tgl@sss.pgh.pa.us       16573                 :              5 :         PQExpBuffer tag = createPQExpBuffer();
                              16574                 :                : 
                              16575                 :              5 :         appendPQExpBuffer(tag, "%s %s", type, name);
 5509 rhaas@postgresql.org    16576                 :              5 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    16577                 :              5 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16578                 :                :                                   .namespace = namespace,
                              16579                 :                :                                   .owner = owner,
                              16580                 :                :                                   .description = "SECURITY LABEL",
                              16581                 :                :                                   .section = SECTION_NONE,
                              16582                 :                :                                   .createStmt = query->data,
                              16583                 :                :                                   .deps = &dumpId,
                              16584                 :                :                                   .nDeps = 1));
 2800 tgl@sss.pgh.pa.us       16585                 :              5 :         destroyPQExpBuffer(tag);
                              16586                 :                :     }
                              16587                 :                : 
 5509 rhaas@postgresql.org    16588                 :             10 :     destroyPQExpBuffer(query);
                              16589                 :                : }
                              16590                 :                : 
                              16591                 :                : /*
                              16592                 :                :  * dumpTableSecLabel
                              16593                 :                :  *
                              16594                 :                :  * As above, but dump security label for both the specified table (or view)
                              16595                 :                :  * and its columns.
                              16596                 :                :  */
                              16597                 :                : static void
 1720 peter@eisentraut.org    16598                 :UBC           0 : dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
                              16599                 :                : {
 3575 tgl@sss.pgh.pa.us       16600                 :              0 :     DumpOptions *dopt = fout->dopt;
                              16601                 :                :     SecLabelItem *labels;
                              16602                 :                :     int         nlabels;
                              16603                 :                :     int         i;
                              16604                 :                :     PQExpBuffer query;
                              16605                 :                :     PQExpBuffer target;
                              16606                 :                : 
                              16607                 :                :     /* do nothing, if --no-security-labels is supplied */
 4031 alvherre@alvh.no-ip.    16608         [ #  # ]:              0 :     if (dopt->no_security_labels)
 5509 rhaas@postgresql.org    16609                 :              0 :         return;
                              16610                 :                : 
                              16611                 :                :     /* SecLabel are SCHEMA not data */
  336 nathan@postgresql.or    16612         [ #  # ]:              0 :     if (!dopt->dumpSchema)
 5509 rhaas@postgresql.org    16613                 :              0 :         return;
                              16614                 :                : 
                              16615                 :                :     /* Search for comments associated with relation, using table */
 1397 tgl@sss.pgh.pa.us       16616                 :              0 :     nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
 5509 rhaas@postgresql.org    16617                 :              0 :                             tbinfo->dobj.catId.oid,
                              16618                 :                :                             &labels);
                              16619                 :                : 
                              16620                 :                :     /* If security labels exist, build SECURITY LABEL statements */
                              16621         [ #  # ]:              0 :     if (nlabels <= 0)
                              16622                 :              0 :         return;
                              16623                 :                : 
                              16624                 :              0 :     query = createPQExpBuffer();
                              16625                 :              0 :     target = createPQExpBuffer();
                              16626                 :                : 
                              16627         [ #  # ]:              0 :     for (i = 0; i < nlabels; i++)
                              16628                 :                :     {
                              16629                 :                :         const char *colname;
 5314 bruce@momjian.us        16630                 :              0 :         const char *provider = labels[i].provider;
                              16631                 :              0 :         const char *label = labels[i].label;
                              16632                 :              0 :         int         objsubid = labels[i].objsubid;
                              16633                 :                : 
 5509 rhaas@postgresql.org    16634                 :              0 :         resetPQExpBuffer(target);
                              16635         [ #  # ]:              0 :         if (objsubid == 0)
                              16636                 :                :         {
                              16637                 :              0 :             appendPQExpBuffer(target, "%s %s", reltypename,
 2800 tgl@sss.pgh.pa.us       16638                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              16639                 :                :         }
                              16640                 :                :         else
                              16641                 :                :         {
 5509 rhaas@postgresql.org    16642                 :              0 :             colname = getAttrName(objsubid, tbinfo);
                              16643                 :                :             /* first fmtXXX result must be consumed before calling again */
 2800 tgl@sss.pgh.pa.us       16644                 :              0 :             appendPQExpBuffer(target, "COLUMN %s",
                              16645                 :              0 :                               fmtQualifiedDumpable(tbinfo));
 5413 rhaas@postgresql.org    16646                 :              0 :             appendPQExpBuffer(target, ".%s", fmtId(colname));
                              16647                 :                :         }
 5509                         16648                 :              0 :         appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
                              16649                 :                :                           fmtId(provider), target->data);
                              16650                 :              0 :         appendStringLiteralAH(query, label, fout);
 4361 heikki.linnakangas@i    16651                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              16652                 :                :     }
 5509 rhaas@postgresql.org    16653         [ #  # ]:              0 :     if (query->len > 0)
                              16654                 :                :     {
                              16655                 :              0 :         resetPQExpBuffer(target);
                              16656                 :              0 :         appendPQExpBuffer(target, "%s %s", reltypename,
                              16657                 :              0 :                           fmtId(tbinfo->dobj.name));
                              16658                 :              0 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    16659                 :              0 :                      ARCHIVE_OPTS(.tag = target->data,
                              16660                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              16661                 :                :                                   .owner = tbinfo->rolname,
                              16662                 :                :                                   .description = "SECURITY LABEL",
                              16663                 :                :                                   .section = SECTION_NONE,
                              16664                 :                :                                   .createStmt = query->data,
                              16665                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              16666                 :                :                                   .nDeps = 1));
                              16667                 :                :     }
 5509 rhaas@postgresql.org    16668                 :              0 :     destroyPQExpBuffer(query);
                              16669                 :              0 :     destroyPQExpBuffer(target);
                              16670                 :                : }
                              16671                 :                : 
                              16672                 :                : /*
                              16673                 :                :  * findSecLabels
                              16674                 :                :  *
                              16675                 :                :  * Find the security label(s), if any, associated with the given object.
                              16676                 :                :  * All the objsubid values associated with the given classoid/objoid are
                              16677                 :                :  * found with one search.
                              16678                 :                :  */
                              16679                 :                : static int
 1397 tgl@sss.pgh.pa.us       16680                 :GBC          10 : findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
                              16681                 :                : {
 5314 bruce@momjian.us        16682                 :             10 :     SecLabelItem *middle = NULL;
                              16683                 :                :     SecLabelItem *low;
                              16684                 :                :     SecLabelItem *high;
                              16685                 :                :     int         nmatch;
                              16686                 :                : 
 1421 tgl@sss.pgh.pa.us       16687         [ -  + ]:             10 :     if (nseclabels <= 0)     /* no labels, so no match is possible */
                              16688                 :                :     {
 5100 tgl@sss.pgh.pa.us       16689                 :UBC           0 :         *items = NULL;
                              16690                 :              0 :         return 0;
                              16691                 :                :     }
                              16692                 :                : 
                              16693                 :                :     /*
                              16694                 :                :      * Do binary search to find some item matching the object.
                              16695                 :                :      */
 1421 tgl@sss.pgh.pa.us       16696                 :GBC          10 :     low = &seclabels[0];
                              16697                 :             10 :     high = &seclabels[nseclabels - 1];
 5509 rhaas@postgresql.org    16698         [ +  + ]:             15 :     while (low <= high)
                              16699                 :                :     {
                              16700                 :             10 :         middle = low + (high - low) / 2;
                              16701                 :                : 
                              16702         [ -  + ]:             10 :         if (classoid < middle->classoid)
 5509 rhaas@postgresql.org    16703                 :UBC           0 :             high = middle - 1;
 5509 rhaas@postgresql.org    16704         [ -  + ]:GBC          10 :         else if (classoid > middle->classoid)
 5509 rhaas@postgresql.org    16705                 :UBC           0 :             low = middle + 1;
 5509 rhaas@postgresql.org    16706         [ +  + ]:GBC          10 :         else if (objoid < middle->objoid)
                              16707                 :              5 :             high = middle - 1;
                              16708         [ -  + ]:              5 :         else if (objoid > middle->objoid)
 5509 rhaas@postgresql.org    16709                 :UBC           0 :             low = middle + 1;
                              16710                 :                :         else
 5314 bruce@momjian.us        16711                 :GBC           5 :             break;              /* found a match */
                              16712                 :                :     }
                              16713                 :                : 
                              16714         [ +  + ]:             10 :     if (low > high)              /* no matches */
                              16715                 :                :     {
 5509 rhaas@postgresql.org    16716                 :              5 :         *items = NULL;
                              16717                 :              5 :         return 0;
                              16718                 :                :     }
                              16719                 :                : 
                              16720                 :                :     /*
                              16721                 :                :      * Now determine how many items match the object.  The search loop
                              16722                 :                :      * invariant still holds: only items between low and high inclusive could
                              16723                 :                :      * match.
                              16724                 :                :      */
                              16725                 :              5 :     nmatch = 1;
                              16726         [ -  + ]:              5 :     while (middle > low)
                              16727                 :                :     {
 5509 rhaas@postgresql.org    16728         [ #  # ]:UBC           0 :         if (classoid != middle[-1].classoid ||
                              16729         [ #  # ]:              0 :             objoid != middle[-1].objoid)
                              16730                 :                :             break;
                              16731                 :              0 :         middle--;
                              16732                 :              0 :         nmatch++;
                              16733                 :                :     }
                              16734                 :                : 
 5509 rhaas@postgresql.org    16735                 :GBC           5 :     *items = middle;
                              16736                 :                : 
                              16737                 :              5 :     middle += nmatch;
                              16738         [ -  + ]:              5 :     while (middle <= high)
                              16739                 :                :     {
 5509 rhaas@postgresql.org    16740         [ #  # ]:UBC           0 :         if (classoid != middle->classoid ||
                              16741         [ #  # ]:              0 :             objoid != middle->objoid)
                              16742                 :                :             break;
                              16743                 :              0 :         middle++;
                              16744                 :              0 :         nmatch++;
                              16745                 :                :     }
                              16746                 :                : 
 5509 rhaas@postgresql.org    16747                 :GBC           5 :     return nmatch;
                              16748                 :                : }
                              16749                 :                : 
                              16750                 :                : /*
                              16751                 :                :  * collectSecLabels
                              16752                 :                :  *
                              16753                 :                :  * Construct a table of all security labels available for database objects;
                              16754                 :                :  * also set the has-seclabel component flag for each relevant object.
                              16755                 :                :  *
                              16756                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              16757                 :                :  */
                              16758                 :                : static void
 1421 tgl@sss.pgh.pa.us       16759                 :CBC         189 : collectSecLabels(Archive *fout)
                              16760                 :                : {
                              16761                 :                :     PGresult   *res;
                              16762                 :                :     PQExpBuffer query;
                              16763                 :                :     int         i_label;
                              16764                 :                :     int         i_provider;
                              16765                 :                :     int         i_classoid;
                              16766                 :                :     int         i_objoid;
                              16767                 :                :     int         i_objsubid;
                              16768                 :                :     int         ntups;
                              16769                 :                :     int         i;
                              16770                 :                :     DumpableObject *dobj;
                              16771                 :                : 
 5509 rhaas@postgresql.org    16772                 :            189 :     query = createPQExpBuffer();
                              16773                 :                : 
 4361 heikki.linnakangas@i    16774                 :            189 :     appendPQExpBufferStr(query,
                              16775                 :                :                          "SELECT label, provider, classoid, objoid, objsubid "
                              16776                 :                :                          "FROM pg_catalog.pg_seclabels "
                              16777                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              16778                 :                : 
 5011 rhaas@postgresql.org    16779                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16780                 :                : 
                              16781                 :                :     /* Construct lookup table containing OIDs in numeric form */
 5314 bruce@momjian.us        16782                 :            189 :     i_label = PQfnumber(res, "label");
                              16783                 :            189 :     i_provider = PQfnumber(res, "provider");
                              16784                 :            189 :     i_classoid = PQfnumber(res, "classoid");
                              16785                 :            189 :     i_objoid = PQfnumber(res, "objoid");
                              16786                 :            189 :     i_objsubid = PQfnumber(res, "objsubid");
                              16787                 :                : 
 5509 rhaas@postgresql.org    16788                 :            189 :     ntups = PQntuples(res);
                              16789                 :                : 
 1421 tgl@sss.pgh.pa.us       16790                 :            189 :     seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
                              16791                 :            189 :     nseclabels = 0;
                              16792                 :            189 :     dobj = NULL;
                              16793                 :                : 
 5509 rhaas@postgresql.org    16794         [ +  + ]:            194 :     for (i = 0; i < ntups; i++)
                              16795                 :                :     {
                              16796                 :                :         CatalogId   objId;
                              16797                 :                :         int         subid;
                              16798                 :                : 
 1421 tgl@sss.pgh.pa.us       16799                 :GBC           5 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              16800                 :              5 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              16801                 :              5 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              16802                 :                : 
                              16803                 :                :         /* We needn't remember labels that don't match any dumpable object */
                              16804         [ -  + ]:              5 :         if (dobj == NULL ||
 1421 tgl@sss.pgh.pa.us       16805         [ #  # ]:UBC           0 :             dobj->catId.tableoid != objId.tableoid ||
                              16806         [ #  # ]:              0 :             dobj->catId.oid != objId.oid)
 1421 tgl@sss.pgh.pa.us       16807                 :GBC           5 :             dobj = findObjectByCatalogId(objId);
                              16808         [ -  + ]:              5 :         if (dobj == NULL)
 1421 tgl@sss.pgh.pa.us       16809                 :UBC           0 :             continue;
                              16810                 :                : 
                              16811                 :                :         /*
                              16812                 :                :          * Labels on columns of composite types are linked to the type's
                              16813                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
                              16814                 :                :          * in the type's own DumpableObject.
                              16815                 :                :          */
 1421 tgl@sss.pgh.pa.us       16816   [ -  +  -  - ]:GBC           5 :         if (subid != 0 && dobj->objType == DO_TABLE &&
 1421 tgl@sss.pgh.pa.us       16817         [ #  # ]:UBC           0 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              16818                 :              0 :         {
                              16819                 :                :             TypeInfo   *cTypeInfo;
                              16820                 :                : 
                              16821                 :              0 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              16822         [ #  # ]:              0 :             if (cTypeInfo)
                              16823                 :              0 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
                              16824                 :                :         }
                              16825                 :                :         else
 1421 tgl@sss.pgh.pa.us       16826                 :GBC           5 :             dobj->components |= DUMP_COMPONENT_SECLABEL;
                              16827                 :                : 
                              16828                 :              5 :         seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
                              16829                 :              5 :         seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
                              16830                 :              5 :         seclabels[nseclabels].classoid = objId.tableoid;
                              16831                 :              5 :         seclabels[nseclabels].objoid = objId.oid;
                              16832                 :              5 :         seclabels[nseclabels].objsubid = subid;
                              16833                 :              5 :         nseclabels++;
                              16834                 :                :     }
                              16835                 :                : 
 1421 tgl@sss.pgh.pa.us       16836                 :CBC         189 :     PQclear(res);
 5314 bruce@momjian.us        16837                 :            189 :     destroyPQExpBuffer(query);
 5509 rhaas@postgresql.org    16838                 :            189 : }
                              16839                 :                : 
                              16840                 :                : /*
                              16841                 :                :  * dumpTable
                              16842                 :                :  *    write out to fout the declarations (not data) of a user-defined table
                              16843                 :                :  */
                              16844                 :                : static void
 1720 peter@eisentraut.org    16845                 :          31464 : dumpTable(Archive *fout, const TableInfo *tbinfo)
                              16846                 :                : {
 3491 sfrost@snowman.net      16847                 :          31464 :     DumpOptions *dopt = fout->dopt;
 1934 tgl@sss.pgh.pa.us       16848                 :          31464 :     DumpId      tableAclDumpId = InvalidDumpId;
                              16849                 :                :     char       *namecopy;
                              16850                 :                : 
                              16851                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    16852         [ +  + ]:          31464 :     if (!dopt->dumpSchema)
 3489 sfrost@snowman.net      16853                 :           1508 :         return;
                              16854                 :                : 
 1421 tgl@sss.pgh.pa.us       16855         [ +  + ]:          29956 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16856                 :                :     {
                              16857         [ +  + ]:           6589 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
                              16858                 :            375 :             dumpSequence(fout, tbinfo);
                              16859                 :                :         else
                              16860                 :           6214 :             dumpTableSchema(fout, tbinfo);
                              16861                 :                :     }
                              16862                 :                : 
                              16863                 :                :     /* Handle the ACL here */
 3491 sfrost@snowman.net      16864                 :          29956 :     namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
                              16865         [ +  + ]:          29956 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              16866                 :                :     {
 2835 tgl@sss.pgh.pa.us       16867                 :          24088 :         const char *objtype =
  892                         16868         [ +  + ]:          24088 :             (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
                              16869                 :                : 
                              16870                 :                :         tableAclDumpId =
 1934                         16871                 :          24088 :             dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
                              16872                 :                :                     objtype, namecopy, NULL,
  574                         16873                 :          24088 :                     tbinfo->dobj.namespace->dobj.name,
                              16874                 :          24088 :                     NULL, tbinfo->rolname, &tbinfo->dacl);
                              16875                 :                :     }
                              16876                 :                : 
                              16877                 :                :     /*
                              16878                 :                :      * Handle column ACLs, if any.  Note: we pull these with a separate query
                              16879                 :                :      * rather than trying to fetch them during getTableAttrs, so that we won't
                              16880                 :                :      * miss ACLs on system columns.  Doing it this way also allows us to dump
                              16881                 :                :      * ACLs for catalogs that we didn't mark "interesting" back in getTables.
                              16882                 :                :      */
 1421                         16883   [ +  +  +  + ]:          29956 :     if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
                              16884                 :                :     {
 3491 sfrost@snowman.net      16885                 :            284 :         PQExpBuffer query = createPQExpBuffer();
                              16886                 :                :         PGresult   *res;
                              16887                 :                :         int         i;
                              16888                 :                : 
 1421 tgl@sss.pgh.pa.us       16889         [ +  + ]:            284 :         if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS])
                              16890                 :                :         {
                              16891                 :                :             /* Set up query for column ACLs */
                              16892                 :            163 :             appendPQExpBufferStr(query,
                              16893                 :                :                                  "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
                              16894                 :                : 
                              16895         [ +  - ]:            163 :             if (fout->remoteVersion >= 90600)
                              16896                 :                :             {
                              16897                 :                :                 /*
                              16898                 :                :                  * In principle we should call acldefault('c', relowner) to
                              16899                 :                :                  * get the default ACL for a column.  However, we don't
                              16900                 :                :                  * currently store the numeric OID of the relowner in
                              16901                 :                :                  * TableInfo.  We could convert the owner name using regrole,
                              16902                 :                :                  * but that creates a risk of failure due to concurrent role
                              16903                 :                :                  * renames.  Given that the default ACL for columns is empty
                              16904                 :                :                  * and is likely to stay that way, it's not worth extra cycles
                              16905                 :                :                  * and risk to avoid hard-wiring that knowledge here.
                              16906                 :                :                  */
                              16907                 :            163 :                 appendPQExpBufferStr(query,
                              16908                 :                :                                      "SELECT at.attname, "
                              16909                 :                :                                      "at.attacl, "
                              16910                 :                :                                      "'{}' AS acldefault, "
                              16911                 :                :                                      "pip.privtype, pip.initprivs "
                              16912                 :                :                                      "FROM pg_catalog.pg_attribute at "
                              16913                 :                :                                      "LEFT JOIN pg_catalog.pg_init_privs pip ON "
                              16914                 :                :                                      "(at.attrelid = pip.objoid "
                              16915                 :                :                                      "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
                              16916                 :                :                                      "AND at.attnum = pip.objsubid) "
                              16917                 :                :                                      "WHERE at.attrelid = $1 AND "
                              16918                 :                :                                      "NOT at.attisdropped "
                              16919                 :                :                                      "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
                              16920                 :                :                                      "ORDER BY at.attnum");
                              16921                 :                :             }
                              16922                 :                :             else
                              16923                 :                :             {
 1421 tgl@sss.pgh.pa.us       16924                 :UBC           0 :                 appendPQExpBufferStr(query,
                              16925                 :                :                                      "SELECT attname, attacl, '{}' AS acldefault, "
                              16926                 :                :                                      "NULL AS privtype, NULL AS initprivs "
                              16927                 :                :                                      "FROM pg_catalog.pg_attribute "
                              16928                 :                :                                      "WHERE attrelid = $1 AND NOT attisdropped "
                              16929                 :                :                                      "AND attacl IS NOT NULL "
                              16930                 :                :                                      "ORDER BY attnum");
                              16931                 :                :             }
                              16932                 :                : 
 1421 tgl@sss.pgh.pa.us       16933                 :CBC         163 :             ExecuteSqlStatement(fout, query->data);
                              16934                 :                : 
                              16935                 :            163 :             fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
                              16936                 :                :         }
                              16937                 :                : 
                              16938                 :            284 :         printfPQExpBuffer(query,
                              16939                 :                :                           "EXECUTE getColumnACLs('%u')",
                              16940                 :            284 :                           tbinfo->dobj.catId.oid);
                              16941                 :                : 
 3491 sfrost@snowman.net      16942                 :            284 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16943                 :                : 
                              16944         [ +  + ]:           4531 :         for (i = 0; i < PQntuples(res); i++)
                              16945                 :                :         {
                              16946                 :           4247 :             char       *attname = PQgetvalue(res, i, 0);
                              16947                 :           4247 :             char       *attacl = PQgetvalue(res, i, 1);
 1421 tgl@sss.pgh.pa.us       16948                 :           4247 :             char       *acldefault = PQgetvalue(res, i, 2);
                              16949                 :           4247 :             char        privtype = *(PQgetvalue(res, i, 3));
                              16950                 :           4247 :             char       *initprivs = PQgetvalue(res, i, 4);
                              16951                 :                :             DumpableAcl coldacl;
                              16952                 :                :             char       *attnamecopy;
                              16953                 :                : 
                              16954                 :           4247 :             coldacl.acl = attacl;
                              16955                 :           4247 :             coldacl.acldefault = acldefault;
                              16956                 :           4247 :             coldacl.privtype = privtype;
                              16957                 :           4247 :             coldacl.initprivs = initprivs;
 3491 sfrost@snowman.net      16958                 :           4247 :             attnamecopy = pg_strdup(fmtId(attname));
                              16959                 :                : 
                              16960                 :                :             /*
                              16961                 :                :              * Column's GRANT type is always TABLE.  Each column ACL depends
                              16962                 :                :              * on the table-level ACL, since we can restore column ACLs in
                              16963                 :                :              * parallel but the table-level ACL has to be done first.
                              16964                 :                :              */
 1934 tgl@sss.pgh.pa.us       16965                 :           4247 :             dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
                              16966                 :                :                     "TABLE", namecopy, attnamecopy,
  574                         16967                 :           4247 :                     tbinfo->dobj.namespace->dobj.name,
                              16968                 :           4247 :                     NULL, tbinfo->rolname, &coldacl);
 3491 sfrost@snowman.net      16969                 :           4247 :             free(attnamecopy);
                              16970                 :                :         }
                              16971                 :            284 :         PQclear(res);
                              16972                 :            284 :         destroyPQExpBuffer(query);
                              16973                 :                :     }
                              16974                 :                : 
                              16975                 :          29956 :     free(namecopy);
                              16976                 :                : }
                              16977                 :                : 
                              16978                 :                : /*
                              16979                 :                :  * Create the AS clause for a view or materialized view. The semicolon is
                              16980                 :                :  * stripped because a materialized view must add a WITH NO DATA clause.
                              16981                 :                :  *
                              16982                 :                :  * This returns a new buffer which must be freed by the caller.
                              16983                 :                :  */
                              16984                 :                : static PQExpBuffer
 1720 peter@eisentraut.org    16985                 :            871 : createViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              16986                 :                : {
 4621 kgrittn@postgresql.o    16987                 :            871 :     PQExpBuffer query = createPQExpBuffer();
                              16988                 :            871 :     PQExpBuffer result = createPQExpBuffer();
                              16989                 :                :     PGresult   *res;
                              16990                 :                :     int         len;
                              16991                 :                : 
                              16992                 :                :     /* Fetch the view definition */
 3302 tgl@sss.pgh.pa.us       16993                 :            871 :     appendPQExpBuffer(query,
                              16994                 :                :                       "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
                              16995                 :            871 :                       tbinfo->dobj.catId.oid);
                              16996                 :                : 
 4621 kgrittn@postgresql.o    16997                 :            871 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16998                 :                : 
                              16999         [ -  + ]:            871 :     if (PQntuples(res) != 1)
                              17000                 :                :     {
 4621 kgrittn@postgresql.o    17001         [ #  # ]:UBC           0 :         if (PQntuples(res) < 1)
 1298 tgl@sss.pgh.pa.us       17002                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned no data",
                              17003                 :                :                      tbinfo->dobj.name);
                              17004                 :                :         else
                              17005                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
                              17006                 :                :                      tbinfo->dobj.name);
                              17007                 :                :     }
                              17008                 :                : 
 4621 kgrittn@postgresql.o    17009                 :CBC         871 :     len = PQgetlength(res, 0, 0);
                              17010                 :                : 
                              17011         [ -  + ]:            871 :     if (len == 0)
 1298 tgl@sss.pgh.pa.us       17012                 :UBC           0 :         pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
                              17013                 :                :                  tbinfo->dobj.name);
                              17014                 :                : 
                              17015                 :                :     /* Strip off the trailing semicolon so that other things may follow. */
 4600 andrew@dunslane.net     17016         [ -  + ]:CBC         871 :     Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
 4621 kgrittn@postgresql.o    17017                 :            871 :     appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
                              17018                 :                : 
                              17019                 :            871 :     PQclear(res);
                              17020                 :            871 :     destroyPQExpBuffer(query);
                              17021                 :                : 
                              17022                 :            871 :     return result;
                              17023                 :                : }
                              17024                 :                : 
                              17025                 :                : /*
                              17026                 :                :  * Create a dummy AS clause for a view.  This is used when the real view
                              17027                 :                :  * definition has to be postponed because of circular dependencies.
                              17028                 :                :  * We must duplicate the view's external properties -- column names and types
                              17029                 :                :  * (including collation) -- so that it works for subsequent references.
                              17030                 :                :  *
                              17031                 :                :  * This returns a new buffer which must be freed by the caller.
                              17032                 :                :  */
                              17033                 :                : static PQExpBuffer
 1720 peter@eisentraut.org    17034                 :             20 : createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              17035                 :                : {
 3266 tgl@sss.pgh.pa.us       17036                 :             20 :     PQExpBuffer result = createPQExpBuffer();
                              17037                 :                :     int         j;
                              17038                 :                : 
                              17039                 :             20 :     appendPQExpBufferStr(result, "SELECT");
                              17040                 :                : 
                              17041         [ +  + ]:             40 :     for (j = 0; j < tbinfo->numatts; j++)
                              17042                 :                :     {
                              17043         [ +  + ]:             20 :         if (j > 0)
                              17044                 :             10 :             appendPQExpBufferChar(result, ',');
                              17045                 :             20 :         appendPQExpBufferStr(result, "\n    ");
                              17046                 :                : 
                              17047                 :             20 :         appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
                              17048                 :                : 
                              17049                 :                :         /*
                              17050                 :                :          * Must add collation if not default for the type, because CREATE OR
                              17051                 :                :          * REPLACE VIEW won't change it
                              17052                 :                :          */
                              17053         [ -  + ]:             20 :         if (OidIsValid(tbinfo->attcollation[j]))
                              17054                 :                :         {
                              17055                 :                :             CollInfo   *coll;
                              17056                 :                : 
 3266 tgl@sss.pgh.pa.us       17057                 :UBC           0 :             coll = findCollationByOid(tbinfo->attcollation[j]);
                              17058         [ #  # ]:              0 :             if (coll)
 2800                         17059                 :              0 :                 appendPQExpBuffer(result, " COLLATE %s",
                              17060                 :              0 :                                   fmtQualifiedDumpable(coll));
                              17061                 :                :         }
                              17062                 :                : 
 3266 tgl@sss.pgh.pa.us       17063                 :CBC          20 :         appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
                              17064                 :                :     }
                              17065                 :                : 
                              17066                 :             20 :     return result;
                              17067                 :                : }
                              17068                 :                : 
                              17069                 :                : /*
                              17070                 :                :  * dumpTableSchema
                              17071                 :                :  *    write the declaration (not data) of one user-defined table or view
                              17072                 :                :  */
                              17073                 :                : static void
 1720 peter@eisentraut.org    17074                 :           6214 : dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
                              17075                 :                : {
 3575 tgl@sss.pgh.pa.us       17076                 :           6214 :     DumpOptions *dopt = fout->dopt;
 9329 bruce@momjian.us        17077                 :           6214 :     PQExpBuffer q = createPQExpBuffer();
 9246                         17078                 :           6214 :     PQExpBuffer delq = createPQExpBuffer();
  455 tgl@sss.pgh.pa.us       17079                 :           6214 :     PQExpBuffer extra = createPQExpBuffer();
                              17080                 :                :     char       *qrelname;
                              17081                 :                :     char       *qualrelname;
                              17082                 :                :     int         numParents;
                              17083                 :                :     TableInfo **parents;
                              17084                 :                :     int         actual_atts;    /* number of attrs in this CREATE statement */
                              17085                 :                :     const char *reltypename;
                              17086                 :                :     char       *storage;
                              17087                 :                :     int         j,
                              17088                 :                :                 k;
                              17089                 :                : 
                              17090                 :                :     /* We had better have loaded per-column details about this table */
 1846                         17091         [ -  + ]:           6214 :     Assert(tbinfo->interesting);
                              17092                 :                : 
 2800                         17093                 :           6214 :     qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
                              17094                 :           6214 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              17095                 :                : 
 2533 andres@anarazel.de      17096         [ -  + ]:           6214 :     if (tbinfo->hasoids)
 2401 peter@eisentraut.org    17097                 :UBC           0 :         pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
                              17098                 :                :                        qrelname);
                              17099                 :                : 
 4031 alvherre@alvh.no-ip.    17100         [ +  + ]:CBC        6214 :     if (dopt->binary_upgrade)
 1421 tgl@sss.pgh.pa.us       17101                 :            866 :         binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
                              17102                 :                : 
                              17103                 :                :     /* Is it a table or a view? */
 8571                         17104         [ +  + ]:           6214 :     if (tbinfo->relkind == RELKIND_VIEW)
                              17105                 :                :     {
                              17106                 :                :         PQExpBuffer result;
                              17107                 :                : 
                              17108                 :                :         /*
                              17109                 :                :          * Note: keep this code in sync with the is_view case in dumpRule()
                              17110                 :                :          */
                              17111                 :                : 
                              17112                 :            533 :         reltypename = "VIEW";
                              17113                 :                : 
 2800                         17114                 :            533 :         appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
                              17115                 :                : 
 4031 alvherre@alvh.no-ip.    17116         [ +  + ]:            533 :         if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    17117                 :             52 :             binary_upgrade_set_pg_class_oids(fout, q,
  481 nathan@postgresql.or    17118                 :             52 :                                              tbinfo->dobj.catId.oid);
                              17119                 :                : 
 2800 tgl@sss.pgh.pa.us       17120                 :            533 :         appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
                              17121                 :                : 
 3266                         17122         [ +  + ]:            533 :         if (tbinfo->dummy_view)
                              17123                 :             10 :             result = createDummyViewAsClause(fout, tbinfo);
                              17124                 :                :         else
                              17125                 :                :         {
                              17126         [ +  + ]:            523 :             if (nonemptyReloptions(tbinfo->reloptions))
                              17127                 :                :             {
                              17128                 :             61 :                 appendPQExpBufferStr(q, " WITH (");
                              17129                 :             61 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              17130                 :             61 :                 appendPQExpBufferChar(q, ')');
                              17131                 :                :             }
                              17132                 :            523 :             result = createViewAsClause(fout, tbinfo);
                              17133                 :                :         }
 4484 sfrost@snowman.net      17134                 :            533 :         appendPQExpBuffer(q, " AS\n%s", result->data);
 4621 kgrittn@postgresql.o    17135                 :            533 :         destroyPQExpBuffer(result);
                              17136                 :                : 
 3266 tgl@sss.pgh.pa.us       17137   [ +  +  +  - ]:            533 :         if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
 4484 sfrost@snowman.net      17138                 :             32 :             appendPQExpBuffer(q, "\n  WITH %s CHECK OPTION", tbinfo->checkoption);
 4361 heikki.linnakangas@i    17139                 :            533 :         appendPQExpBufferStr(q, ";\n");
                              17140                 :                :     }
                              17141                 :                :     else
                              17142                 :                :     {
 1421 tgl@sss.pgh.pa.us       17143                 :           5681 :         char       *partkeydef = NULL;
 2517 sfrost@snowman.net      17144                 :           5681 :         char       *ftoptions = NULL;
                              17145                 :           5681 :         char       *srvname = NULL;
  455 tgl@sss.pgh.pa.us       17146                 :           5681 :         const char *foreign = "";
                              17147                 :                : 
                              17148                 :                :         /*
                              17149                 :                :          * Set reltypename, and collect any relkind-specific data that we
                              17150                 :                :          * didn't fetch during getTables().
                              17151                 :                :          */
 4621 kgrittn@postgresql.o    17152   [ +  +  +  + ]:           5681 :         switch (tbinfo->relkind)
                              17153                 :                :         {
 1421 tgl@sss.pgh.pa.us       17154                 :            566 :             case RELKIND_PARTITIONED_TABLE:
                              17155                 :                :                 {
                              17156                 :            566 :                     PQExpBuffer query = createPQExpBuffer();
                              17157                 :                :                     PGresult   *res;
                              17158                 :                : 
                              17159                 :            566 :                     reltypename = "TABLE";
                              17160                 :                : 
                              17161                 :                :                     /* retrieve partition key definition */
                              17162                 :            566 :                     appendPQExpBuffer(query,
                              17163                 :                :                                       "SELECT pg_get_partkeydef('%u')",
                              17164                 :            566 :                                       tbinfo->dobj.catId.oid);
                              17165                 :            566 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              17166                 :            566 :                     partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
                              17167                 :            566 :                     PQclear(res);
                              17168                 :            566 :                     destroyPQExpBuffer(query);
                              17169                 :            566 :                     break;
                              17170                 :                :                 }
 3154                         17171                 :             34 :             case RELKIND_FOREIGN_TABLE:
                              17172                 :                :                 {
 4600 andrew@dunslane.net     17173                 :             34 :                     PQExpBuffer query = createPQExpBuffer();
                              17174                 :                :                     PGresult   *res;
                              17175                 :                :                     int         i_srvname;
                              17176                 :                :                     int         i_ftoptions;
                              17177                 :                : 
                              17178                 :             34 :                     reltypename = "FOREIGN TABLE";
                              17179                 :                : 
                              17180                 :                :                     /* retrieve name of foreign server and generic options */
                              17181                 :             34 :                     appendPQExpBuffer(query,
                              17182                 :                :                                       "SELECT fs.srvname, "
                              17183                 :                :                                       "pg_catalog.array_to_string(ARRAY("
                              17184                 :                :                                       "SELECT pg_catalog.quote_ident(option_name) || "
                              17185                 :                :                                       "' ' || pg_catalog.quote_literal(option_value) "
                              17186                 :                :                                       "FROM pg_catalog.pg_options_to_table(ftoptions) "
                              17187                 :                :                                       "ORDER BY option_name"
                              17188                 :                :                                       "), E',\n    ') AS ftoptions "
                              17189                 :                :                                       "FROM pg_catalog.pg_foreign_table ft "
                              17190                 :                :                                       "JOIN pg_catalog.pg_foreign_server fs "
                              17191                 :                :                                       "ON (fs.oid = ft.ftserver) "
                              17192                 :                :                                       "WHERE ft.ftrelid = '%u'",
                              17193                 :             34 :                                       tbinfo->dobj.catId.oid);
                              17194                 :             34 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              17195                 :             34 :                     i_srvname = PQfnumber(res, "srvname");
                              17196                 :             34 :                     i_ftoptions = PQfnumber(res, "ftoptions");
                              17197                 :             34 :                     srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
                              17198                 :             34 :                     ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
                              17199                 :             34 :                     PQclear(res);
                              17200                 :             34 :                     destroyPQExpBuffer(query);
                              17201                 :                : 
 2047 alvherre@alvh.no-ip.    17202                 :             34 :                     foreign = "FOREIGN ";
 4600 andrew@dunslane.net     17203                 :             34 :                     break;
                              17204                 :                :                 }
 3154 tgl@sss.pgh.pa.us       17205                 :            338 :             case RELKIND_MATVIEW:
 4621 kgrittn@postgresql.o    17206                 :            338 :                 reltypename = "MATERIALIZED VIEW";
                              17207                 :            338 :                 break;
                              17208                 :           4743 :             default:
                              17209                 :           4743 :                 reltypename = "TABLE";
 1421 tgl@sss.pgh.pa.us       17210                 :           4743 :                 break;
                              17211                 :                :         }
                              17212                 :                : 
 8571                         17213                 :           5681 :         numParents = tbinfo->numParents;
 7996                         17214                 :           5681 :         parents = tbinfo->parents;
                              17215                 :                : 
 2800                         17216                 :           5681 :         appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
                              17217                 :                : 
 4031 alvherre@alvh.no-ip.    17218         [ +  + ]:           5681 :         if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    17219                 :            814 :             binary_upgrade_set_pg_class_oids(fout, q,
  481 nathan@postgresql.or    17220                 :            814 :                                              tbinfo->dobj.catId.oid);
                              17221                 :                : 
                              17222                 :                :         /*
                              17223                 :                :          * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so
                              17224                 :                :          * ignore it when dumping if it was set in this case.
                              17225                 :                :          */
 5413 rhaas@postgresql.org    17226                 :           5681 :         appendPQExpBuffer(q, "CREATE %s%s %s",
  389 michael@paquier.xyz     17227         [ +  + ]:           5681 :                           (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
                              17228         [ +  - ]:             20 :                            tbinfo->relkind != RELKIND_PARTITIONED_TABLE) ?
                              17229                 :                :                           "UNLOGGED " : "",
                              17230                 :                :                           reltypename,
                              17231                 :                :                           qualrelname);
                              17232                 :                : 
                              17233                 :                :         /*
                              17234                 :                :          * Attach to type, if reloftype; except in case of a binary upgrade,
                              17235                 :                :          * we dump the table normally and attach it to the type afterward.
                              17236                 :                :          */
 1421 tgl@sss.pgh.pa.us       17237   [ +  +  +  + ]:           5681 :         if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
                              17238                 :             24 :             appendPQExpBuffer(q, " OF %s",
                              17239                 :             24 :                               getFormattedTypeName(fout, tbinfo->reloftype,
                              17240                 :                :                                                    zeroIsError));
                              17241                 :                : 
 4621 kgrittn@postgresql.o    17242         [ +  + ]:           5681 :         if (tbinfo->relkind != RELKIND_MATVIEW)
                              17243                 :                :         {
                              17244                 :                :             /* Dump the attributes */
 4600 andrew@dunslane.net     17245                 :           5343 :             actual_atts = 0;
                              17246         [ +  + ]:          25138 :             for (j = 0; j < tbinfo->numatts; j++)
                              17247                 :                :             {
                              17248                 :                :                 /*
                              17249                 :                :                  * Normally, dump if it's locally defined in this table, and
                              17250                 :                :                  * not dropped.  But for binary upgrade, we'll dump all the
                              17251                 :                :                  * columns, and then fix up the dropped and nonlocal cases
                              17252                 :                :                  * below.
                              17253                 :                :                  */
 4031 alvherre@alvh.no-ip.    17254         [ +  + ]:          19795 :                 if (shouldPrintColumn(dopt, tbinfo, j))
                              17255                 :                :                 {
                              17256                 :                :                     bool        print_default;
                              17257                 :                :                     bool        print_notnull;
                              17258                 :                : 
                              17259                 :                :                     /*
                              17260                 :                :                      * Default value --- suppress if to be printed separately
                              17261                 :                :                      * or not at all.
                              17262                 :                :                      */
 2331                         17263                 :          38667 :                     print_default = (tbinfo->attrdefs[j] != NULL &&
  972 tgl@sss.pgh.pa.us       17264   [ +  +  +  + ]:          19808 :                                      tbinfo->attrdefs[j]->dobj.dump &&
 2331 alvherre@alvh.no-ip.    17265         [ +  + ]:            996 :                                      !tbinfo->attrdefs[j]->separate);
                              17266                 :                : 
                              17267                 :                :                     /*
                              17268                 :                :                      * Not Null constraint --- print it if it is locally
                              17269                 :                :                      * defined, or if binary upgrade.  (In the latter case, we
                              17270                 :                :                      * reset conislocal below.)
                              17271                 :                :                      */
  353                         17272         [ +  + ]:          21027 :                     print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
                              17273         [ +  + ]:           2215 :                                      (tbinfo->notnull_islocal[j] ||
                              17274         [ +  + ]:            607 :                                       dopt->binary_upgrade ||
                              17275         [ +  + ]:            523 :                                       tbinfo->ispartition));
                              17276                 :                : 
                              17277                 :                :                     /*
                              17278                 :                :                      * Skip column if fully defined by reloftype, except in
                              17279                 :                :                      * binary upgrade
                              17280                 :                :                      */
 1421 tgl@sss.pgh.pa.us       17281         [ +  + ]:          18812 :                     if (OidIsValid(tbinfo->reloftype) &&
                              17282   [ +  +  +  + ]:             50 :                         !print_default && !print_notnull &&
 2331 alvherre@alvh.no-ip.    17283         [ +  + ]:             30 :                         !dopt->binary_upgrade)
 4600 andrew@dunslane.net     17284                 :             24 :                         continue;
                              17285                 :                : 
                              17286                 :                :                     /* Format properly if not first attr */
                              17287         [ +  + ]:          18788 :                     if (actual_atts == 0)
 4361 heikki.linnakangas@i    17288                 :           5017 :                         appendPQExpBufferStr(q, " (");
                              17289                 :                :                     else
 3770                         17290                 :          13771 :                         appendPQExpBufferChar(q, ',');
 4361                         17291                 :          18788 :                     appendPQExpBufferStr(q, "\n    ");
 4600 andrew@dunslane.net     17292                 :          18788 :                     actual_atts++;
                              17293                 :                : 
                              17294                 :                :                     /* Attribute name */
 4361 heikki.linnakangas@i    17295                 :          18788 :                     appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
                              17296                 :                : 
 4600 andrew@dunslane.net     17297         [ +  + ]:          18788 :                     if (tbinfo->attisdropped[j])
                              17298                 :                :                     {
                              17299                 :                :                         /*
                              17300                 :                :                          * ALTER TABLE DROP COLUMN clears
                              17301                 :                :                          * pg_attribute.atttypid, so we will not have gotten a
                              17302                 :                :                          * valid type name; insert INTEGER as a stopgap. We'll
                              17303                 :                :                          * clean things up later.
                              17304                 :                :                          */
 4361 heikki.linnakangas@i    17305                 :             84 :                         appendPQExpBufferStr(q, " INTEGER /* dummy */");
                              17306                 :                :                         /* and skip to the next column */
 4600 andrew@dunslane.net     17307                 :             84 :                         continue;
                              17308                 :                :                     }
                              17309                 :                : 
                              17310                 :                :                     /*
                              17311                 :                :                      * Attribute type; print it except when creating a typed
                              17312                 :                :                      * table ('OF type_name'), but in binary-upgrade mode,
                              17313                 :                :                      * print it in that case too.
                              17314                 :                :                      */
 1421 tgl@sss.pgh.pa.us       17315   [ +  +  +  + ]:          18704 :                     if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
                              17316                 :                :                     {
 4600 andrew@dunslane.net     17317                 :          18688 :                         appendPQExpBuffer(q, " %s",
 3302 tgl@sss.pgh.pa.us       17318                 :          18688 :                                           tbinfo->atttypnames[j]);
                              17319                 :                :                     }
                              17320                 :                : 
 2331 alvherre@alvh.no-ip.    17321         [ +  + ]:          18704 :                     if (print_default)
                              17322                 :                :                     {
 2403 peter@eisentraut.org    17323         [ +  + ]:            866 :                         if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
                              17324                 :            277 :                             appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
                              17325                 :            277 :                                               tbinfo->attrdefs[j]->adef_expr);
  262                         17326         [ +  + ]:            589 :                         else if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_VIRTUAL)
                              17327                 :            223 :                             appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s)",
                              17328                 :            223 :                                               tbinfo->attrdefs[j]->adef_expr);
                              17329                 :                :                         else
 2403                         17330                 :            366 :                             appendPQExpBuffer(q, " DEFAULT %s",
                              17331                 :            366 :                                               tbinfo->attrdefs[j]->adef_expr);
                              17332                 :                :                     }
                              17333                 :                : 
 2331 alvherre@alvh.no-ip.    17334         [ +  + ]:          18704 :                     if (print_notnull)
                              17335                 :                :                     {
  353                         17336         [ +  + ]:           2184 :                         if (tbinfo->notnull_constrs[j][0] == '\0')
                              17337                 :           1550 :                             appendPQExpBufferStr(q, " NOT NULL");
                              17338                 :                :                         else
                              17339                 :            634 :                             appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
                              17340                 :            634 :                                               fmtId(tbinfo->notnull_constrs[j]));
                              17341                 :                : 
                              17342         [ -  + ]:           2184 :                         if (tbinfo->notnull_noinh[j])
  353 alvherre@alvh.no-ip.    17343                 :UBC           0 :                             appendPQExpBufferStr(q, " NO INHERIT");
                              17344                 :                :                     }
                              17345                 :                : 
                              17346                 :                :                     /* Add collation if not default for the type */
 4600 andrew@dunslane.net     17347         [ +  + ]:CBC       18704 :                     if (OidIsValid(tbinfo->attcollation[j]))
                              17348                 :                :                     {
                              17349                 :                :                         CollInfo   *coll;
                              17350                 :                : 
                              17351                 :            197 :                         coll = findCollationByOid(tbinfo->attcollation[j]);
                              17352         [ +  - ]:            197 :                         if (coll)
 2800 tgl@sss.pgh.pa.us       17353                 :            197 :                             appendPQExpBuffer(q, " COLLATE %s",
                              17354                 :            197 :                                               fmtQualifiedDumpable(coll));
                              17355                 :                :                     }
                              17356                 :                :                 }
                              17357                 :                : 
                              17358                 :                :                 /*
                              17359                 :                :                  * On the other hand, if we choose not to print a column
                              17360                 :                :                  * (likely because it is created by inheritance), but the
                              17361                 :                :                  * column has a locally-defined not-null constraint, we need
                              17362                 :                :                  * to dump the constraint as a standalone object.
                              17363                 :                :                  *
                              17364                 :                :                  * This syntax isn't SQL-conforming, but if you wanted
                              17365                 :                :                  * standard output you wouldn't be creating non-standard
                              17366                 :                :                  * objects to begin with.
                              17367                 :                :                  */
  318 alvherre@alvh.no-ip.    17368         [ +  + ]:          19687 :                 if (!shouldPrintColumn(dopt, tbinfo, j) &&
                              17369         [ +  + ]:            983 :                     !tbinfo->attisdropped[j] &&
                              17370         [ +  + ]:            620 :                     tbinfo->notnull_constrs[j] != NULL &&
                              17371         [ +  + ]:            177 :                     tbinfo->notnull_islocal[j])
                              17372                 :                :                 {
                              17373                 :                :                     /* Format properly if not first attr */
                              17374         [ +  + ]:             59 :                     if (actual_atts == 0)
                              17375                 :             55 :                         appendPQExpBufferStr(q, " (");
                              17376                 :                :                     else
                              17377                 :              4 :                         appendPQExpBufferChar(q, ',');
                              17378                 :             59 :                     appendPQExpBufferStr(q, "\n    ");
                              17379                 :             59 :                     actual_atts++;
                              17380                 :                : 
                              17381         [ +  + ]:             59 :                     if (tbinfo->notnull_constrs[j][0] == '\0')
                              17382                 :              8 :                         appendPQExpBuffer(q, "NOT NULL %s",
                              17383                 :              8 :                                           fmtId(tbinfo->attnames[j]));
                              17384                 :                :                     else
                              17385                 :            102 :                         appendPQExpBuffer(q, "CONSTRAINT %s NOT NULL %s",
                              17386                 :             51 :                                           tbinfo->notnull_constrs[j],
                              17387                 :             51 :                                           fmtId(tbinfo->attnames[j]));
                              17388                 :                :                 }
                              17389                 :                :             }
                              17390                 :                : 
                              17391                 :                :             /*
                              17392                 :                :              * Add non-inherited CHECK constraints, if any.
                              17393                 :                :              *
                              17394                 :                :              * For partitions, we need to include check constraints even if
                              17395                 :                :              * they're not defined locally, because the ALTER TABLE ATTACH
                              17396                 :                :              * PARTITION that we'll emit later expects the constraint to be
                              17397                 :                :              * there.  (No need to fix conislocal: ATTACH PARTITION does that)
                              17398                 :                :              */
 4600 andrew@dunslane.net     17399         [ +  + ]:           5916 :             for (j = 0; j < tbinfo->ncheck; j++)
                              17400                 :                :             {
                              17401                 :            573 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              17402                 :                : 
 2331 alvherre@alvh.no-ip.    17403         [ +  + ]:            573 :                 if (constr->separate ||
                              17404   [ +  +  +  + ]:            503 :                     (!constr->conislocal && !tbinfo->ispartition))
 4600 andrew@dunslane.net     17405                 :            107 :                     continue;
                              17406                 :                : 
                              17407         [ +  + ]:            466 :                 if (actual_atts == 0)
 4361 heikki.linnakangas@i    17408                 :             16 :                     appendPQExpBufferStr(q, " (\n    ");
                              17409                 :                :                 else
                              17410                 :            450 :                     appendPQExpBufferStr(q, ",\n    ");
                              17411                 :                : 
 4600 andrew@dunslane.net     17412                 :            466 :                 appendPQExpBuffer(q, "CONSTRAINT %s ",
                              17413                 :            466 :                                   fmtId(constr->dobj.name));
 4361 heikki.linnakangas@i    17414                 :            466 :                 appendPQExpBufferStr(q, constr->condef);
                              17415                 :                : 
 4600 andrew@dunslane.net     17416                 :            466 :                 actual_atts++;
                              17417                 :                :             }
                              17418                 :                : 
                              17419         [ +  + ]:           5343 :             if (actual_atts)
 4361 heikki.linnakangas@i    17420                 :           5088 :                 appendPQExpBufferStr(q, "\n)");
 1421 tgl@sss.pgh.pa.us       17421   [ +  +  -  + ]:            255 :             else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
                              17422                 :                :             {
                              17423                 :                :                 /*
                              17424                 :                :                  * No attributes? we must have a parenthesized attribute list,
                              17425                 :                :                  * even though empty, when not using the OF TYPE syntax.
                              17426                 :                :                  */
 4361 heikki.linnakangas@i    17427                 :            243 :                 appendPQExpBufferStr(q, " (\n)");
                              17428                 :                :             }
                              17429                 :                : 
                              17430                 :                :             /*
                              17431                 :                :              * Emit the INHERITS clause (not for partitions), except in
                              17432                 :                :              * binary-upgrade mode.
                              17433                 :                :              */
 2331 alvherre@alvh.no-ip.    17434   [ +  +  +  + ]:           5343 :             if (numParents > 0 && !tbinfo->ispartition &&
 3098 sfrost@snowman.net      17435         [ +  + ]:            489 :                 !dopt->binary_upgrade)
                              17436                 :                :             {
 4361 heikki.linnakangas@i    17437                 :            425 :                 appendPQExpBufferStr(q, "\nINHERITS (");
 4600 andrew@dunslane.net     17438         [ +  + ]:            921 :                 for (k = 0; k < numParents; k++)
                              17439                 :                :                 {
                              17440                 :            496 :                     TableInfo  *parentRel = parents[k];
                              17441                 :                : 
                              17442         [ +  + ]:            496 :                     if (k > 0)
 4361 heikki.linnakangas@i    17443                 :             71 :                         appendPQExpBufferStr(q, ", ");
 2800 tgl@sss.pgh.pa.us       17444                 :            496 :                     appendPQExpBufferStr(q, fmtQualifiedDumpable(parentRel));
                              17445                 :                :                 }
 4361 heikki.linnakangas@i    17446                 :            425 :                 appendPQExpBufferChar(q, ')');
                              17447                 :                :             }
                              17448                 :                : 
 3246 rhaas@postgresql.org    17449         [ +  + ]:           5343 :             if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 1421 tgl@sss.pgh.pa.us       17450                 :            566 :                 appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
                              17451                 :                : 
 4600 andrew@dunslane.net     17452         [ +  + ]:           5343 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                              17453                 :             34 :                 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
                              17454                 :                :         }
                              17455                 :                : 
 3586 tgl@sss.pgh.pa.us       17456   [ +  +  -  + ]:          11220 :         if (nonemptyReloptions(tbinfo->reloptions) ||
                              17457                 :           5539 :             nonemptyReloptions(tbinfo->toast_reloptions))
                              17458                 :                :         {
 5982 bruce@momjian.us        17459                 :            142 :             bool        addcomma = false;
                              17460                 :                : 
 4361 heikki.linnakangas@i    17461                 :            142 :             appendPQExpBufferStr(q, "\nWITH (");
 3586 tgl@sss.pgh.pa.us       17462         [ +  - ]:            142 :             if (nonemptyReloptions(tbinfo->reloptions))
                              17463                 :                :             {
 6111 alvherre@alvh.no-ip.    17464                 :            142 :                 addcomma = true;
 3461 dean.a.rasheed@gmail    17465                 :            142 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              17466                 :                :             }
 3586 tgl@sss.pgh.pa.us       17467         [ +  + ]:            142 :             if (nonemptyReloptions(tbinfo->toast_reloptions))
                              17468                 :                :             {
                              17469         [ +  - ]:              5 :                 if (addcomma)
                              17470                 :              5 :                     appendPQExpBufferStr(q, ", ");
 3461 dean.a.rasheed@gmail    17471                 :              5 :                 appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
                              17472                 :                :                                         fout);
                              17473                 :                :             }
 4361 heikki.linnakangas@i    17474                 :            142 :             appendPQExpBufferChar(q, ')');
                              17475                 :                :         }
                              17476                 :                : 
                              17477                 :                :         /* Dump generic options if any */
 5413 rhaas@postgresql.org    17478   [ +  +  +  + ]:           5681 :         if (ftoptions && ftoptions[0])
 5044 peter_e@gmx.net         17479                 :             32 :             appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);
                              17480                 :                : 
                              17481                 :                :         /*
                              17482                 :                :          * For materialized views, create the AS clause just like a view. At
                              17483                 :                :          * this point, we always mark the view as not populated.
                              17484                 :                :          */
 4621 kgrittn@postgresql.o    17485         [ +  + ]:           5681 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              17486                 :                :         {
                              17487                 :                :             PQExpBuffer result;
                              17488                 :                : 
                              17489                 :            338 :             result = createViewAsClause(fout, tbinfo);
                              17490                 :            338 :             appendPQExpBuffer(q, " AS\n%s\n  WITH NO DATA;\n",
                              17491                 :                :                               result->data);
                              17492                 :            338 :             destroyPQExpBuffer(result);
                              17493                 :                :         }
                              17494                 :                :         else
 4361 heikki.linnakangas@i    17495                 :           5343 :             appendPQExpBufferStr(q, ";\n");
                              17496                 :                : 
                              17497                 :                :         /* Materialized views can depend on extensions */
 2056 alvherre@alvh.no-ip.    17498         [ +  + ]:           5681 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              17499                 :            338 :             append_depends_on_extension(fout, q, &tbinfo->dobj,
                              17500                 :                :                                         "pg_catalog.pg_class",
                              17501                 :                :                                         "MATERIALIZED VIEW",
                              17502                 :                :                                         qualrelname);
                              17503                 :                : 
                              17504                 :                :         /*
                              17505                 :                :          * in binary upgrade mode, update the catalog with any missing values
                              17506                 :                :          * that might be present.
                              17507                 :                :          */
 2684 andrew@dunslane.net     17508         [ +  + ]:           5681 :         if (dopt->binary_upgrade)
                              17509                 :                :         {
                              17510         [ +  + ]:           3953 :             for (j = 0; j < tbinfo->numatts; j++)
                              17511                 :                :             {
                              17512         [ +  + ]:           3139 :                 if (tbinfo->attmissingval[j][0] != '\0')
                              17513                 :                :                 {
                              17514                 :              2 :                     appendPQExpBufferStr(q, "\n-- set missing value.\n");
                              17515                 :              2 :                     appendPQExpBufferStr(q,
                              17516                 :                :                                          "SELECT pg_catalog.binary_upgrade_set_missing_value(");
                              17517                 :              2 :                     appendStringLiteralAH(q, qualrelname, fout);
                              17518                 :              2 :                     appendPQExpBufferStr(q, "::pg_catalog.regclass,");
                              17519                 :              2 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 1147 drowley@postgresql.o    17520                 :              2 :                     appendPQExpBufferChar(q, ',');
 2684 andrew@dunslane.net     17521                 :              2 :                     appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
                              17522                 :              2 :                     appendPQExpBufferStr(q, ");\n\n");
                              17523                 :                :                 }
                              17524                 :                :             }
                              17525                 :                :         }
                              17526                 :                : 
                              17527                 :                :         /*
                              17528                 :                :          * To create binary-compatible heap files, we have to ensure the same
                              17529                 :                :          * physical column order, including dropped columns, as in the
                              17530                 :                :          * original.  Therefore, we create dropped columns above and drop them
                              17531                 :                :          * here, also updating their attlen/attalign values so that the
                              17532                 :                :          * dropped column can be skipped properly.  (We do not bother with
                              17533                 :                :          * restoring the original attbyval setting.)  Also, inheritance
                              17534                 :                :          * relationships are set up by doing ALTER TABLE INHERIT rather than
                              17535                 :                :          * using an INHERITS clause --- the latter would possibly mess up the
                              17536                 :                :          * column order.  That also means we have to take care about setting
                              17537                 :                :          * attislocal correctly, plus fix up any inherited CHECK constraints.
                              17538                 :                :          * Analogously, we set up typed tables using ALTER TABLE / OF here.
                              17539                 :                :          *
                              17540                 :                :          * We process foreign and partitioned tables here, even though they
                              17541                 :                :          * lack heap storage, because they can participate in inheritance
                              17542                 :                :          * relationships and we want this stuff to be consistent across the
                              17543                 :                :          * inheritance tree.  We can exclude indexes, toast tables, sequences
                              17544                 :                :          * and matviews, even though they have storage, because we don't
                              17545                 :                :          * support altering or dropping columns in them, nor can they be part
                              17546                 :                :          * of inheritance trees.
                              17547                 :                :          */
 3872 tgl@sss.pgh.pa.us       17548         [ +  + ]:           5681 :         if (dopt->binary_upgrade &&
                              17549         [ +  + ]:            814 :             (tbinfo->relkind == RELKIND_RELATION ||
 3246 rhaas@postgresql.org    17550         [ +  + ]:            109 :              tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
                              17551         [ +  + ]:            108 :              tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
                              17552                 :                :         {
                              17553                 :                :             bool        firstitem;
                              17554                 :                :             bool        firstitem_extra;
                              17555                 :                : 
                              17556                 :                :             /*
                              17557                 :                :              * Drop any dropped columns.  Merge the pg_attribute manipulations
                              17558                 :                :              * into a single SQL command, so that we don't cause repeated
                              17559                 :                :              * relcache flushes on the target table.  Otherwise we risk O(N^2)
                              17560                 :                :              * relcache bloat while dropping N columns.
                              17561                 :                :              */
  455 tgl@sss.pgh.pa.us       17562                 :            797 :             resetPQExpBuffer(extra);
                              17563                 :            797 :             firstitem = true;
 6096 bruce@momjian.us        17564         [ +  + ]:           3915 :             for (j = 0; j < tbinfo->numatts; j++)
                              17565                 :                :             {
                              17566         [ +  + ]:           3118 :                 if (tbinfo->attisdropped[j])
                              17567                 :                :                 {
  455 tgl@sss.pgh.pa.us       17568         [ +  + ]:             84 :                     if (firstitem)
                              17569                 :                :                     {
                              17570                 :             38 :                         appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped columns.\n"
                              17571                 :                :                                              "UPDATE pg_catalog.pg_attribute\n"
                              17572                 :                :                                              "SET attlen = v.dlen, "
                              17573                 :                :                                              "attalign = v.dalign, "
                              17574                 :                :                                              "attbyval = false\n"
                              17575                 :                :                                              "FROM (VALUES ");
                              17576                 :             38 :                         firstitem = false;
                              17577                 :                :                     }
                              17578                 :                :                     else
                              17579                 :             46 :                         appendPQExpBufferStr(q, ",\n             ");
                              17580                 :             84 :                     appendPQExpBufferChar(q, '(');
                              17581                 :             84 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                              17582                 :             84 :                     appendPQExpBuffer(q, ", %d, '%c')",
 5961                         17583                 :             84 :                                       tbinfo->attlen[j],
                              17584                 :             84 :                                       tbinfo->attalign[j]);
                              17585                 :                :                     /* The ALTER ... DROP COLUMN commands must come after */
  455                         17586                 :             84 :                     appendPQExpBuffer(extra, "ALTER %sTABLE ONLY %s ",
                              17587                 :                :                                       foreign, qualrelname);
                              17588                 :             84 :                     appendPQExpBuffer(extra, "DROP COLUMN %s;\n",
 6096 bruce@momjian.us        17589                 :             84 :                                       fmtId(tbinfo->attnames[j]));
                              17590                 :                :                 }
                              17591                 :                :             }
  455 tgl@sss.pgh.pa.us       17592         [ +  + ]:            797 :             if (!firstitem)
                              17593                 :                :             {
                              17594                 :             38 :                 appendPQExpBufferStr(q, ") v(dname, dlen, dalign)\n"
                              17595                 :                :                                      "WHERE attrelid = ");
                              17596                 :             38 :                 appendStringLiteralAH(q, qualrelname, fout);
                              17597                 :             38 :                 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
                              17598                 :                :                                      "  AND attname = v.dname;\n");
                              17599                 :                :                 /* Now we can issue the actual DROP COLUMN commands */
                              17600                 :             38 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17601                 :                :             }
                              17602                 :                : 
                              17603                 :                :             /*
                              17604                 :                :              * Fix up inherited columns.  As above, do the pg_attribute
                              17605                 :                :              * manipulations in a single SQL command.
                              17606                 :                :              */
                              17607                 :            797 :             firstitem = true;
                              17608         [ +  + ]:           3915 :             for (j = 0; j < tbinfo->numatts; j++)
                              17609                 :                :             {
                              17610         [ +  + ]:           3118 :                 if (!tbinfo->attisdropped[j] &&
                              17611         [ +  + ]:           3034 :                     !tbinfo->attislocal[j])
                              17612                 :                :                 {
                              17613         [ +  + ]:            604 :                     if (firstitem)
                              17614                 :                :                     {
                              17615                 :            267 :                         appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited columns.\n");
                              17616                 :            267 :                         appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
                              17617                 :                :                                              "SET attislocal = false\n"
                              17618                 :                :                                              "WHERE attrelid = ");
                              17619                 :            267 :                         appendStringLiteralAH(q, qualrelname, fout);
                              17620                 :            267 :                         appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
                              17621                 :                :                                              "  AND attname IN (");
                              17622                 :            267 :                         firstitem = false;
                              17623                 :                :                     }
                              17624                 :                :                     else
                              17625                 :            337 :                         appendPQExpBufferStr(q, ", ");
 5961                         17626                 :            604 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                              17627                 :                :                 }
                              17628                 :                :             }
  455                         17629         [ +  + ]:            797 :             if (!firstitem)
                              17630                 :            267 :                 appendPQExpBufferStr(q, ");\n");
                              17631                 :                : 
                              17632                 :                :             /*
                              17633                 :                :              * Fix up not-null constraints that come from inheritance.  As
                              17634                 :                :              * above, do the pg_constraint manipulations in a single SQL
                              17635                 :                :              * command.  (Actually, two in special cases, if we're doing an
                              17636                 :                :              * upgrade from < 18).
                              17637                 :                :              */
  353 alvherre@alvh.no-ip.    17638                 :            797 :             firstitem = true;
                              17639                 :            797 :             firstitem_extra = true;
                              17640                 :            797 :             resetPQExpBuffer(extra);
                              17641         [ +  + ]:           3915 :             for (j = 0; j < tbinfo->numatts; j++)
                              17642                 :                :             {
                              17643                 :                :                 /*
                              17644                 :                :                  * If a not-null constraint comes from inheritance, reset
                              17645                 :                :                  * conislocal.  The inhcount is fixed by ALTER TABLE INHERIT,
                              17646                 :                :                  * below.  Special hack: in versions < 18, columns with no
                              17647                 :                :                  * local definition need their constraint to be matched by
                              17648                 :                :                  * column number in conkeys instead of by constraint name,
                              17649                 :                :                  * because the latter is not available.  (We distinguish the
                              17650                 :                :                  * case because the constraint name is the empty string.)
                              17651                 :                :                  */
                              17652         [ +  + ]:           3118 :                 if (tbinfo->notnull_constrs[j] != NULL &&
                              17653         [ +  + ]:            291 :                     !tbinfo->notnull_islocal[j])
                              17654                 :                :                 {
                              17655         [ +  + ]:             84 :                     if (tbinfo->notnull_constrs[j][0] != '\0')
                              17656                 :                :                     {
                              17657         [ +  + ]:             71 :                         if (firstitem)
                              17658                 :                :                         {
                              17659                 :             61 :                             appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
                              17660                 :                :                                                  "SET conislocal = false\n"
                              17661                 :                :                                                  "WHERE contype = 'n' AND conrelid = ");
                              17662                 :             61 :                             appendStringLiteralAH(q, qualrelname, fout);
                              17663                 :             61 :                             appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
                              17664                 :                :                                                  "conname IN (");
                              17665                 :             61 :                             firstitem = false;
                              17666                 :                :                         }
                              17667                 :                :                         else
                              17668                 :             10 :                             appendPQExpBufferStr(q, ", ");
                              17669                 :             71 :                         appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
                              17670                 :                :                     }
                              17671                 :                :                     else
                              17672                 :                :                     {
                              17673         [ +  - ]:             13 :                         if (firstitem_extra)
                              17674                 :                :                         {
                              17675                 :             13 :                             appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
                              17676                 :                :                                                  "SET conislocal = false\n"
                              17677                 :                :                                                  "WHERE contype = 'n' AND conrelid = ");
                              17678                 :             13 :                             appendStringLiteralAH(extra, qualrelname, fout);
                              17679                 :             13 :                             appendPQExpBufferStr(extra, "::pg_catalog.regclass AND\n"
                              17680                 :                :                                                  "conkey IN (");
                              17681                 :             13 :                             firstitem_extra = false;
                              17682                 :                :                         }
                              17683                 :                :                         else
  353 alvherre@alvh.no-ip.    17684                 :UBC           0 :                             appendPQExpBufferStr(extra, ", ");
  353 alvherre@alvh.no-ip.    17685                 :CBC          13 :                         appendPQExpBuffer(extra, "'{%d}'", j + 1);
                              17686                 :                :                     }
                              17687                 :                :                 }
                              17688                 :                :             }
                              17689         [ +  + ]:            797 :             if (!firstitem)
                              17690                 :             61 :                 appendPQExpBufferStr(q, ");\n");
                              17691         [ +  + ]:            797 :             if (!firstitem_extra)
                              17692                 :             13 :                 appendPQExpBufferStr(extra, ");\n");
                              17693                 :                : 
                              17694         [ +  + ]:            797 :             if (extra->len > 0)
                              17695                 :             13 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17696                 :                : 
                              17697                 :                :             /*
                              17698                 :                :              * Add inherited CHECK constraints, if any.
                              17699                 :                :              *
                              17700                 :                :              * For partitions, they were already dumped, and conislocal
                              17701                 :                :              * doesn't need fixing.
                              17702                 :                :              *
                              17703                 :                :              * As above, issue only one direct manipulation of pg_constraint.
                              17704                 :                :              * Although it is tempting to merge the ALTER ADD CONSTRAINT
                              17705                 :                :              * commands into one as well, refrain for now due to concern about
                              17706                 :                :              * possible backend memory bloat if there are many such
                              17707                 :                :              * constraints.
                              17708                 :                :              */
  455 tgl@sss.pgh.pa.us       17709                 :            797 :             resetPQExpBuffer(extra);
                              17710                 :            797 :             firstitem = true;
 5961                         17711         [ +  + ]:            859 :             for (k = 0; k < tbinfo->ncheck; k++)
                              17712                 :                :             {
                              17713                 :             62 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
                              17714                 :                : 
 2331 alvherre@alvh.no-ip.    17715   [ +  +  +  +  :             62 :                 if (constr->separate || constr->conislocal || tbinfo->ispartition)
                                              +  + ]
 5961 tgl@sss.pgh.pa.us       17716                 :             60 :                     continue;
                              17717                 :                : 
  455                         17718         [ +  - ]:              2 :                 if (firstitem)
                              17719                 :              2 :                     appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraints.\n");
 2047 alvherre@alvh.no-ip.    17720                 :              2 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
                              17721                 :                :                                   foreign, qualrelname,
                              17722                 :              2 :                                   fmtId(constr->dobj.name),
                              17723                 :                :                                   constr->condef);
                              17724                 :                :                 /* Update pg_constraint after all the ALTER TABLEs */
  455 tgl@sss.pgh.pa.us       17725         [ +  - ]:              2 :                 if (firstitem)
                              17726                 :                :                 {
                              17727                 :              2 :                     appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
                              17728                 :                :                                          "SET conislocal = false\n"
                              17729                 :                :                                          "WHERE contype = 'c' AND conrelid = ");
                              17730                 :              2 :                     appendStringLiteralAH(extra, qualrelname, fout);
                              17731                 :              2 :                     appendPQExpBufferStr(extra, "::pg_catalog.regclass\n");
                              17732                 :              2 :                     appendPQExpBufferStr(extra, "  AND conname IN (");
                              17733                 :              2 :                     firstitem = false;
                              17734                 :                :                 }
                              17735                 :                :                 else
  455 tgl@sss.pgh.pa.us       17736                 :UBC           0 :                     appendPQExpBufferStr(extra, ", ");
  455 tgl@sss.pgh.pa.us       17737                 :CBC           2 :                 appendStringLiteralAH(extra, constr->dobj.name, fout);
                              17738                 :                :             }
                              17739         [ +  + ]:            797 :             if (!firstitem)
                              17740                 :                :             {
                              17741                 :              2 :                 appendPQExpBufferStr(extra, ");\n");
                              17742                 :              2 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17743                 :                :             }
                              17744                 :                : 
 2331 alvherre@alvh.no-ip.    17745   [ +  +  +  + ]:            797 :             if (numParents > 0 && !tbinfo->ispartition)
                              17746                 :                :             {
                              17747                 :             64 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
 5961 tgl@sss.pgh.pa.us       17748         [ +  + ]:            139 :                 for (k = 0; k < numParents; k++)
                              17749                 :                :                 {
                              17750                 :             75 :                     TableInfo  *parentRel = parents[k];
                              17751                 :                : 
 2047 alvherre@alvh.no-ip.    17752                 :             75 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
                              17753                 :                :                                       qualrelname,
 2331                         17754                 :             75 :                                       fmtQualifiedDumpable(parentRel));
                              17755                 :                :                 }
                              17756                 :                :             }
                              17757                 :                : 
 1421 tgl@sss.pgh.pa.us       17758         [ +  + ]:            797 :             if (OidIsValid(tbinfo->reloftype))
                              17759                 :                :             {
 4361 heikki.linnakangas@i    17760                 :              6 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
 5297 peter_e@gmx.net         17761                 :              6 :                 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
                              17762                 :                :                                   qualrelname,
 1421 tgl@sss.pgh.pa.us       17763                 :              6 :                                   getFormattedTypeName(fout, tbinfo->reloftype,
                              17764                 :                :                                                        zeroIsError));
                              17765                 :                :             }
                              17766                 :                :         }
                              17767                 :                : 
                              17768                 :                :         /*
                              17769                 :                :          * In binary_upgrade mode, arrange to restore the old relfrozenxid and
                              17770                 :                :          * relminmxid of all vacuumable relations.  (While vacuum.c processes
                              17771                 :                :          * TOAST tables semi-independently, here we see them only as children
                              17772                 :                :          * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
                              17773                 :                :          * child toast table is handled below.)
                              17774                 :                :          */
 2805                         17775         [ +  + ]:           5681 :         if (dopt->binary_upgrade &&
                              17776         [ +  + ]:            814 :             (tbinfo->relkind == RELKIND_RELATION ||
                              17777         [ +  + ]:            109 :              tbinfo->relkind == RELKIND_MATVIEW))
                              17778                 :                :         {
 4135 bruce@momjian.us        17779                 :            722 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
 5961 tgl@sss.pgh.pa.us       17780                 :            722 :             appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              17781                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              17782                 :                :                               "WHERE oid = ",
 4135 bruce@momjian.us        17783                 :            722 :                               tbinfo->frozenxid, tbinfo->minmxid);
 2800 tgl@sss.pgh.pa.us       17784                 :            722 :             appendStringLiteralAH(q, qualrelname, fout);
 4361 heikki.linnakangas@i    17785                 :            722 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              17786                 :                : 
 5316 bruce@momjian.us        17787         [ +  + ]:            722 :             if (tbinfo->toast_oid)
                              17788                 :                :             {
                              17789                 :                :                 /*
                              17790                 :                :                  * The toast table will have the same OID at restore, so we
                              17791                 :                :                  * can safely target it by OID.
                              17792                 :                :                  */
 4135                         17793                 :            277 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
 5316                         17794                 :            277 :                 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              17795                 :                :                                   "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              17796                 :                :                                   "WHERE oid = '%u';\n",
 4135                         17797                 :            277 :                                   tbinfo->toast_frozenxid,
                              17798                 :            277 :                                   tbinfo->toast_minmxid, tbinfo->toast_oid);
                              17799                 :                :             }
                              17800                 :                :         }
                              17801                 :                : 
                              17802                 :                :         /*
                              17803                 :                :          * In binary_upgrade mode, restore matviews' populated status by
                              17804                 :                :          * poking pg_class directly.  This is pretty ugly, but we can't use
                              17805                 :                :          * REFRESH MATERIALIZED VIEW since it's possible that some underlying
                              17806                 :                :          * matview is not populated even though this matview is; in any case,
                              17807                 :                :          * we want to transfer the matview's heap storage, not run REFRESH.
                              17808                 :                :          */
 4031 alvherre@alvh.no-ip.    17809   [ +  +  +  + ]:           5681 :         if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
 4557 tgl@sss.pgh.pa.us       17810         [ +  + ]:             17 :             tbinfo->relispopulated)
                              17811                 :                :         {
 4361 heikki.linnakangas@i    17812                 :             15 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
                              17813                 :             15 :             appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
                              17814                 :                :                                  "SET relispopulated = 't'\n"
                              17815                 :                :                                  "WHERE oid = ");
 2800 tgl@sss.pgh.pa.us       17816                 :             15 :             appendStringLiteralAH(q, qualrelname, fout);
 4361 heikki.linnakangas@i    17817                 :             15 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              17818                 :                :         }
                              17819                 :                : 
                              17820                 :                :         /*
                              17821                 :                :          * Dump additional per-column properties that we can't handle in the
                              17822                 :                :          * main CREATE TABLE command.
                              17823                 :                :          */
 8454 bruce@momjian.us        17824         [ +  + ]:          25888 :         for (j = 0; j < tbinfo->numatts; j++)
                              17825                 :                :         {
                              17826                 :                :             /* None of this applies to dropped columns */
 5008 tgl@sss.pgh.pa.us       17827         [ +  + ]:          20207 :             if (tbinfo->attisdropped[j])
                              17828                 :            447 :                 continue;
                              17829                 :                : 
                              17830                 :                :             /*
                              17831                 :                :              * Dump per-column statistics information. We only issue an ALTER
                              17832                 :                :              * TABLE statement if the attstattarget entry for this column is
                              17833                 :                :              * not the default value.
                              17834                 :                :              */
                              17835         [ +  + ]:          19760 :             if (tbinfo->attstattarget[j] >= 0)
 2047 alvherre@alvh.no-ip.    17836                 :             32 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
                              17837                 :                :                                   foreign, qualrelname,
                              17838                 :             32 :                                   fmtId(tbinfo->attnames[j]),
 8489 tgl@sss.pgh.pa.us       17839                 :             32 :                                   tbinfo->attstattarget[j]);
                              17840                 :                : 
                              17841                 :                :             /*
                              17842                 :                :              * Dump per-column storage information.  The statement is only
                              17843                 :                :              * dumped if the storage has been changed from the type's default.
                              17844                 :                :              */
 5008                         17845         [ +  + ]:          19760 :             if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
                              17846                 :                :             {
 8120 bruce@momjian.us        17847   [ +  +  -  +  :             79 :                 switch (tbinfo->attstorage[j])
                                                 - ]
                              17848                 :                :                 {
 2063 tgl@sss.pgh.pa.us       17849                 :             10 :                     case TYPSTORAGE_PLAIN:
 8257 bruce@momjian.us        17850                 :             10 :                         storage = "PLAIN";
                              17851                 :             10 :                         break;
 2063 tgl@sss.pgh.pa.us       17852                 :             37 :                     case TYPSTORAGE_EXTERNAL:
 8257 bruce@momjian.us        17853                 :             37 :                         storage = "EXTERNAL";
                              17854                 :             37 :                         break;
 2063 tgl@sss.pgh.pa.us       17855                 :UBC           0 :                     case TYPSTORAGE_EXTENDED:
 8257 bruce@momjian.us        17856                 :              0 :                         storage = "EXTENDED";
                              17857                 :              0 :                         break;
 2063 tgl@sss.pgh.pa.us       17858                 :CBC          32 :                     case TYPSTORAGE_MAIN:
                              17859                 :             32 :                         storage = "MAIN";
                              17860                 :             32 :                         break;
 8257 bruce@momjian.us        17861                 :UBC           0 :                     default:
                              17862                 :              0 :                         storage = NULL;
                              17863                 :                :                 }
                              17864                 :                : 
                              17865                 :                :                 /*
                              17866                 :                :                  * Only dump the statement if it's a storage type we recognize
                              17867                 :                :                  */
 8120 bruce@momjian.us        17868         [ +  - ]:CBC          79 :                 if (storage != NULL)
 2047 alvherre@alvh.no-ip.    17869                 :             79 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
                              17870                 :                :                                       foreign, qualrelname,
                              17871                 :             79 :                                       fmtId(tbinfo->attnames[j]),
                              17872                 :                :                                       storage);
                              17873                 :                :             }
                              17874                 :                : 
                              17875                 :                :             /*
                              17876                 :                :              * Dump per-column compression, if it's been set.
                              17877                 :                :              */
 1682 tgl@sss.pgh.pa.us       17878         [ +  + ]:          19760 :             if (!dopt->no_toast_compression)
                              17879                 :                :             {
                              17880                 :                :                 const char *cmname;
                              17881                 :                : 
                              17882      [ +  +  + ]:          19666 :                 switch (tbinfo->attcompression[j])
                              17883                 :                :                 {
                              17884                 :             71 :                     case 'p':
                              17885                 :             71 :                         cmname = "pglz";
                              17886                 :             71 :                         break;
                              17887                 :             45 :                     case 'l':
                              17888                 :             45 :                         cmname = "lz4";
                              17889                 :             45 :                         break;
                              17890                 :          19550 :                     default:
                              17891                 :          19550 :                         cmname = NULL;
                              17892                 :          19550 :                         break;
                              17893                 :                :                 }
                              17894                 :                : 
 1614                         17895         [ +  + ]:          19666 :                 if (cmname != NULL)
 1682                         17896                 :            116 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
                              17897                 :                :                                       foreign, qualrelname,
                              17898                 :            116 :                                       fmtId(tbinfo->attnames[j]),
                              17899                 :                :                                       cmname);
                              17900                 :                :             }
                              17901                 :                : 
                              17902                 :                :             /*
                              17903                 :                :              * Dump per-column attributes.
                              17904                 :                :              */
 1614                         17905         [ +  + ]:          19760 :             if (tbinfo->attoptions[j][0] != '\0')
                              17906                 :             32 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
                              17907                 :                :                                   foreign, qualrelname,
                              17908                 :             32 :                                   fmtId(tbinfo->attnames[j]),
                              17909                 :             32 :                                   tbinfo->attoptions[j]);
                              17910                 :                : 
                              17911                 :                :             /*
                              17912                 :                :              * Dump per-column fdw options.
                              17913                 :                :              */
                              17914         [ +  + ]:          19760 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                              17915         [ +  + ]:             34 :                 tbinfo->attfdwoptions[j][0] != '\0')
                              17916                 :             32 :                 appendPQExpBuffer(q,
                              17917                 :                :                                   "ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS (\n"
                              17918                 :                :                                   "    %s\n"
                              17919                 :                :                                   ");\n",
                              17920                 :                :                                   qualrelname,
                              17921                 :             32 :                                   fmtId(tbinfo->attnames[j]),
                              17922                 :             32 :                                   tbinfo->attfdwoptions[j]);
                              17923                 :                :         }                       /* end loop over columns */
                              17924                 :                : 
 1229 peter@eisentraut.org    17925                 :           5681 :         free(partkeydef);
                              17926                 :           5681 :         free(ftoptions);
                              17927                 :           5681 :         free(srvname);
                              17928                 :                :     }
                              17929                 :                : 
                              17930                 :                :     /*
                              17931                 :                :      * dump properties we only have ALTER TABLE syntax for
                              17932                 :                :      */
 3872 tgl@sss.pgh.pa.us       17933         [ +  + ]:           6214 :     if ((tbinfo->relkind == RELKIND_RELATION ||
 3246 rhaas@postgresql.org    17934         [ +  + ]:           1471 :          tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
 3872 tgl@sss.pgh.pa.us       17935         [ +  + ]:            905 :          tbinfo->relkind == RELKIND_MATVIEW) &&
 4369 peter_e@gmx.net         17936         [ +  + ]:           5647 :         tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
                              17937                 :                :     {
 4371 rhaas@postgresql.org    17938         [ +  - ]:            192 :         if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
                              17939                 :                :         {
                              17940                 :                :             /* nothing to do, will be set when the index is dumped */
                              17941                 :                :         }
                              17942         [ +  - ]:            192 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
                              17943                 :                :         {
                              17944                 :            192 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
                              17945                 :                :                               qualrelname);
                              17946                 :                :         }
 4371 rhaas@postgresql.org    17947         [ #  # ]:UBC           0 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
                              17948                 :                :         {
                              17949                 :              0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
                              17950                 :                :                               qualrelname);
                              17951                 :                :         }
                              17952                 :                :     }
                              17953                 :                : 
 3676 sfrost@snowman.net      17954         [ +  + ]:CBC        6214 :     if (tbinfo->forcerowsec)
                              17955                 :              5 :         appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
                              17956                 :                :                           qualrelname);
                              17957                 :                : 
 4031 alvherre@alvh.no-ip.    17958         [ +  + ]:           6214 :     if (dopt->binary_upgrade)
 2800 tgl@sss.pgh.pa.us       17959                 :            866 :         binary_upgrade_extension_member(q, &tbinfo->dobj,
                              17960                 :                :                                         reltypename, qrelname,
                              17961                 :            866 :                                         tbinfo->dobj.namespace->dobj.name);
                              17962                 :                : 
 3491 sfrost@snowman.net      17963         [ +  - ]:           6214 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17964                 :                :     {
 1424 peter@eisentraut.org    17965                 :           6214 :         char       *tablespace = NULL;
 2350 tgl@sss.pgh.pa.us       17966                 :           6214 :         char       *tableam = NULL;
                              17967                 :                : 
                              17968                 :                :         /*
                              17969                 :                :          * _selectTablespace() relies on tablespace-enabled objects in the
                              17970                 :                :          * default tablespace to have a tablespace of "" (empty string) versus
                              17971                 :                :          * non-tablespace-enabled objects to have a tablespace of NULL.
                              17972                 :                :          * getTables() sets tbinfo->reltablespace to "" for the default
                              17973                 :                :          * tablespace (not NULL).
                              17974                 :                :          */
 1424 peter@eisentraut.org    17975   [ +  +  +  -  :           6214 :         if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
                                     +  -  +  -  +  
                                     +  +  +  -  +  
                                              +  - ]
                              17976                 :           5647 :             tablespace = tbinfo->reltablespace;
                              17977                 :                : 
  581 alvherre@alvh.no-ip.    17978   [ +  +  +  -  :           6214 :         if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
                                              +  + ]
                              17979         [ +  + ]:           1133 :             tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 2427 andres@anarazel.de      17980                 :           5647 :             tableam = tbinfo->amname;
                              17981                 :                : 
 3491 sfrost@snowman.net      17982                 :           6214 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    17983         [ +  + ]:           6214 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              17984                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              17985                 :                :                                   .tablespace = tablespace,
                              17986                 :                :                                   .tableam = tableam,
                              17987                 :                :                                   .relkind = tbinfo->relkind,
                              17988                 :                :                                   .owner = tbinfo->rolname,
                              17989                 :                :                                   .description = reltypename,
                              17990                 :                :                                   .section = tbinfo->postponed_def ?
                              17991                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              17992                 :                :                                   .createStmt = q->data,
                              17993                 :                :                                   .dropStmt = delq->data));
                              17994                 :                :     }
                              17995                 :                : 
                              17996                 :                :     /* Dump Table Comments */
 3491 sfrost@snowman.net      17997         [ +  + ]:           6214 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              17998                 :             74 :         dumpTableComment(fout, tbinfo, reltypename);
                              17999                 :                : 
                              18000                 :                :     /* Dump Table Security Labels */
                              18001         [ -  + ]:           6214 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 3491 sfrost@snowman.net      18002                 :UBC           0 :         dumpTableSecLabel(fout, tbinfo, reltypename);
                              18003                 :                : 
                              18004                 :                :     /*
                              18005                 :                :      * Dump comments for not-null constraints that aren't to be dumped
                              18006                 :                :      * separately (those are processed by collectComments/dumpComment).
                              18007                 :                :      */
  123 alvherre@kurilemu.de    18008   [ +  -  +  - ]:CBC        6214 :     if (!fout->dopt->no_comments && dopt->dumpSchema &&
                              18009         [ +  - ]:           6214 :         fout->remoteVersion >= 180000)
                              18010                 :                :     {
                              18011                 :           6214 :         PQExpBuffer comment = NULL;
                              18012                 :           6214 :         PQExpBuffer tag = NULL;
                              18013                 :                : 
                              18014         [ +  + ]:          29820 :         for (j = 0; j < tbinfo->numatts; j++)
                              18015                 :                :         {
                              18016         [ +  + ]:          23606 :             if (tbinfo->notnull_constrs[j] != NULL &&
                              18017         [ +  + ]:           2392 :                 tbinfo->notnull_comment[j] != NULL)
                              18018                 :                :             {
                              18019         [ +  - ]:             42 :                 if (comment == NULL)
                              18020                 :                :                 {
                              18021                 :             42 :                     comment = createPQExpBuffer();
                              18022                 :             42 :                     tag = createPQExpBuffer();
                              18023                 :                :                 }
                              18024                 :                :                 else
                              18025                 :                :                 {
  123 alvherre@kurilemu.de    18026                 :UBC           0 :                     resetPQExpBuffer(comment);
                              18027                 :              0 :                     resetPQExpBuffer(tag);
                              18028                 :                :                 }
                              18029                 :                : 
  123 alvherre@kurilemu.de    18030                 :CBC          42 :                 appendPQExpBuffer(comment, "COMMENT ON CONSTRAINT %s ON %s IS ",
                              18031                 :             42 :                                   fmtId(tbinfo->notnull_constrs[j]), qualrelname);
                              18032                 :             42 :                 appendStringLiteralAH(comment, tbinfo->notnull_comment[j], fout);
                              18033                 :             42 :                 appendPQExpBufferStr(comment, ";\n");
                              18034                 :                : 
                              18035                 :             42 :                 appendPQExpBuffer(tag, "CONSTRAINT %s ON %s",
                              18036                 :             42 :                                   fmtId(tbinfo->notnull_constrs[j]), qrelname);
                              18037                 :                : 
                              18038                 :             42 :                 ArchiveEntry(fout, nilCatalogId, createDumpId(),
                              18039                 :             42 :                              ARCHIVE_OPTS(.tag = tag->data,
                              18040                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              18041                 :                :                                           .owner = tbinfo->rolname,
                              18042                 :                :                                           .description = "COMMENT",
                              18043                 :                :                                           .section = SECTION_NONE,
                              18044                 :                :                                           .createStmt = comment->data,
                              18045                 :                :                                           .deps = &(tbinfo->dobj.dumpId),
                              18046                 :                :                                           .nDeps = 1));
                              18047                 :                :             }
                              18048                 :                :         }
                              18049                 :                : 
                              18050                 :           6214 :         destroyPQExpBuffer(comment);
                              18051                 :           6214 :         destroyPQExpBuffer(tag);
                              18052                 :                :     }
                              18053                 :                : 
                              18054                 :                :     /* Dump comments on inlined table constraints */
 7622 tgl@sss.pgh.pa.us       18055         [ +  + ]:           6787 :     for (j = 0; j < tbinfo->ncheck; j++)
                              18056                 :                :     {
                              18057                 :            573 :         ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              18058                 :                : 
 6380                         18059   [ +  +  +  + ]:            573 :         if (constr->separate || !constr->conislocal)
 7622                         18060                 :            244 :             continue;
                              18061                 :                : 
 1090                         18062         [ +  + ]:            329 :         if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
 3491 sfrost@snowman.net      18063                 :             37 :             dumpTableConstraintComment(fout, constr);
                              18064                 :                :     }
                              18065                 :                : 
 8571 tgl@sss.pgh.pa.us       18066                 :           6214 :     destroyPQExpBuffer(q);
                              18067                 :           6214 :     destroyPQExpBuffer(delq);
  455                         18068                 :           6214 :     destroyPQExpBuffer(extra);
 2800                         18069                 :           6214 :     free(qrelname);
                              18070                 :           6214 :     free(qualrelname);
 9054 pjw@rhyme.com.au        18071                 :           6214 : }
                              18072                 :                : 
                              18073                 :                : /*
                              18074                 :                :  * dumpTableAttach
                              18075                 :                :  *    write to fout the commands to attach a child partition
                              18076                 :                :  *
                              18077                 :                :  * Child partitions are always made by creating them separately
                              18078                 :                :  * and then using ATTACH PARTITION, rather than using
                              18079                 :                :  * CREATE TABLE ... PARTITION OF.  This is important for preserving
                              18080                 :                :  * any possible discrepancy in column layout, to allow assigning the
                              18081                 :                :  * correct tablespace if different, and so that it's possible to restore
                              18082                 :                :  * a partition without restoring its parent.  (You'll get an error from
                              18083                 :                :  * the ATTACH PARTITION command, but that can be ignored, or skipped
                              18084                 :                :  * using "pg_restore -L" if you prefer.)  The last point motivates
                              18085                 :                :  * treating ATTACH PARTITION as a completely separate ArchiveEntry
                              18086                 :                :  * rather than emitting it within the child partition's ArchiveEntry.
                              18087                 :                :  */
                              18088                 :                : static void
 1720 peter@eisentraut.org    18089                 :           1381 : dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
                              18090                 :                : {
 1750 tgl@sss.pgh.pa.us       18091                 :           1381 :     DumpOptions *dopt = fout->dopt;
                              18092                 :                :     PQExpBuffer q;
                              18093                 :                :     PGresult   *res;
                              18094                 :                :     char       *partbound;
                              18095                 :                : 
                              18096                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18097         [ +  + ]:           1381 :     if (!dopt->dumpSchema)
 1750 tgl@sss.pgh.pa.us       18098                 :             54 :         return;
                              18099                 :                : 
                              18100                 :           1327 :     q = createPQExpBuffer();
                              18101                 :                : 
 1421                         18102         [ +  + ]:           1327 :     if (!fout->is_prepared[PREPQUERY_DUMPTABLEATTACH])
                              18103                 :                :     {
                              18104                 :                :         /* Set up query for partbound details */
                              18105                 :             43 :         appendPQExpBufferStr(q,
                              18106                 :                :                              "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
                              18107                 :                : 
                              18108                 :             43 :         appendPQExpBufferStr(q,
                              18109                 :                :                              "SELECT pg_get_expr(c.relpartbound, c.oid) "
                              18110                 :                :                              "FROM pg_class c "
                              18111                 :                :                              "WHERE c.oid = $1");
                              18112                 :                : 
                              18113                 :             43 :         ExecuteSqlStatement(fout, q->data);
                              18114                 :                : 
                              18115                 :             43 :         fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
                              18116                 :                :     }
                              18117                 :                : 
                              18118                 :           1327 :     printfPQExpBuffer(q,
                              18119                 :                :                       "EXECUTE dumpTableAttach('%u')",
                              18120                 :           1327 :                       attachinfo->partitionTbl->dobj.catId.oid);
                              18121                 :                : 
                              18122                 :           1327 :     res = ExecuteSqlQueryForSingleRow(fout, q->data);
                              18123                 :           1327 :     partbound = PQgetvalue(res, 0, 0);
                              18124                 :                : 
                              18125                 :                :     /* Perform ALTER TABLE on the parent */
                              18126                 :           1327 :     printfPQExpBuffer(q,
                              18127                 :                :                       "ALTER TABLE ONLY %s ",
 1750                         18128                 :           1327 :                       fmtQualifiedDumpable(attachinfo->parentTbl));
                              18129                 :           1327 :     appendPQExpBuffer(q,
                              18130                 :                :                       "ATTACH PARTITION %s %s;\n",
                              18131                 :           1327 :                       fmtQualifiedDumpable(attachinfo->partitionTbl),
                              18132                 :                :                       partbound);
                              18133                 :                : 
                              18134                 :                :     /*
                              18135                 :                :      * There is no point in creating a drop query as the drop is done by table
                              18136                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                              18137                 :                :      * Although this object doesn't really have ownership as such, set the
                              18138                 :                :      * owner field anyway to ensure that the command is run by the correct
                              18139                 :                :      * role at restore time.
                              18140                 :                :      */
                              18141                 :           1327 :     ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
                              18142                 :           1327 :                  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              18143                 :                :                               .namespace = attachinfo->dobj.namespace->dobj.name,
                              18144                 :                :                               .owner = attachinfo->partitionTbl->rolname,
                              18145                 :                :                               .description = "TABLE ATTACH",
                              18146                 :                :                               .section = SECTION_PRE_DATA,
                              18147                 :                :                               .createStmt = q->data));
                              18148                 :                : 
 1421                         18149                 :           1327 :     PQclear(res);
 1750                         18150                 :           1327 :     destroyPQExpBuffer(q);
                              18151                 :                : }
                              18152                 :                : 
                              18153                 :                : /*
                              18154                 :                :  * dumpAttrDef --- dump an attribute's default-value declaration
                              18155                 :                :  */
                              18156                 :                : static void
 1720 peter@eisentraut.org    18157                 :           1032 : dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
                              18158                 :                : {
 3575 tgl@sss.pgh.pa.us       18159                 :           1032 :     DumpOptions *dopt = fout->dopt;
 7996                         18160                 :           1032 :     TableInfo  *tbinfo = adinfo->adtable;
                              18161                 :           1032 :     int         adnum = adinfo->adnum;
                              18162                 :                :     PQExpBuffer q;
                              18163                 :                :     PQExpBuffer delq;
                              18164                 :                :     char       *qualrelname;
                              18165                 :                :     char       *tag;
                              18166                 :                :     char       *foreign;
                              18167                 :                : 
                              18168                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18169         [ -  + ]:           1032 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       18170                 :UBC           0 :         return;
                              18171                 :                : 
                              18172                 :                :     /* Skip if not "separate"; it was dumped in the table's definition */
 5008 tgl@sss.pgh.pa.us       18173         [ +  + ]:CBC        1032 :     if (!adinfo->separate)
 7996                         18174                 :            866 :         return;
                              18175                 :                : 
                              18176                 :            166 :     q = createPQExpBuffer();
                              18177                 :            166 :     delq = createPQExpBuffer();
                              18178                 :                : 
 2800                         18179                 :            166 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              18180                 :                : 
 2047 alvherre@alvh.no-ip.    18181         [ -  + ]:            166 :     foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              18182                 :                : 
                              18183                 :            166 :     appendPQExpBuffer(q,
                              18184                 :                :                       "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
                              18185                 :            166 :                       foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
 7996 tgl@sss.pgh.pa.us       18186                 :            166 :                       adinfo->adef_expr);
                              18187                 :                : 
 2047 alvherre@alvh.no-ip.    18188                 :            166 :     appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
                              18189                 :                :                       foreign, qualrelname,
 7996 tgl@sss.pgh.pa.us       18190                 :            166 :                       fmtId(tbinfo->attnames[adnum - 1]));
                              18191                 :                : 
 3532 peter_e@gmx.net         18192                 :            166 :     tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
                              18193                 :                : 
 3491 sfrost@snowman.net      18194         [ +  - ]:            166 :     if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18195                 :            166 :         ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18196                 :            166 :                      ARCHIVE_OPTS(.tag = tag,
                              18197                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              18198                 :                :                                   .owner = tbinfo->rolname,
                              18199                 :                :                                   .description = "DEFAULT",
                              18200                 :                :                                   .section = SECTION_PRE_DATA,
                              18201                 :                :                                   .createStmt = q->data,
                              18202                 :                :                                   .dropStmt = delq->data));
                              18203                 :                : 
 3532 peter_e@gmx.net         18204                 :            166 :     free(tag);
 7996 tgl@sss.pgh.pa.us       18205                 :            166 :     destroyPQExpBuffer(q);
                              18206                 :            166 :     destroyPQExpBuffer(delq);
 2800                         18207                 :            166 :     free(qualrelname);
                              18208                 :                : }
                              18209                 :                : 
                              18210                 :                : /*
                              18211                 :                :  * getAttrName: extract the correct name for an attribute
                              18212                 :                :  *
                              18213                 :                :  * The array tblInfo->attnames[] only provides names of user attributes;
                              18214                 :                :  * if a system attribute number is supplied, we have to fake it.
                              18215                 :                :  * We also do a little bit of bounds checking for safety's sake.
                              18216                 :                :  */
                              18217                 :                : static const char *
 1720 peter@eisentraut.org    18218                 :           2039 : getAttrName(int attrnum, const TableInfo *tblInfo)
                              18219                 :                : {
 8954 tgl@sss.pgh.pa.us       18220   [ +  -  +  - ]:           2039 :     if (attrnum > 0 && attrnum <= tblInfo->numatts)
 8768 bruce@momjian.us        18221                 :           2039 :         return tblInfo->attnames[attrnum - 1];
 8954 tgl@sss.pgh.pa.us       18222   [ #  #  #  #  :UBC           0 :     switch (attrnum)
                                           #  #  # ]
                              18223                 :                :     {
                              18224                 :              0 :         case SelfItemPointerAttributeNumber:
                              18225                 :              0 :             return "ctid";
                              18226                 :              0 :         case MinTransactionIdAttributeNumber:
                              18227                 :              0 :             return "xmin";
                              18228                 :              0 :         case MinCommandIdAttributeNumber:
                              18229                 :              0 :             return "cmin";
                              18230                 :              0 :         case MaxTransactionIdAttributeNumber:
                              18231                 :              0 :             return "xmax";
                              18232                 :              0 :         case MaxCommandIdAttributeNumber:
                              18233                 :              0 :             return "cmax";
                              18234                 :              0 :         case TableOidAttributeNumber:
                              18235                 :              0 :             return "tableoid";
                              18236                 :                :     }
 1298                         18237                 :              0 :     pg_fatal("invalid column number %d for table \"%s\"",
                              18238                 :                :              attrnum, tblInfo->dobj.name);
                              18239                 :                :     return NULL;                /* keep compiler quiet */
                              18240                 :                : }
                              18241                 :                : 
                              18242                 :                : /*
                              18243                 :                :  * dumpIndex
                              18244                 :                :  *    write out to fout a user-defined index
                              18245                 :                :  */
                              18246                 :                : static void
 1720 peter@eisentraut.org    18247                 :CBC        2574 : dumpIndex(Archive *fout, const IndxInfo *indxinfo)
                              18248                 :                : {
 3575 tgl@sss.pgh.pa.us       18249                 :           2574 :     DumpOptions *dopt = fout->dopt;
 7996                         18250                 :           2574 :     TableInfo  *tbinfo = indxinfo->indextable;
 4505                         18251                 :           2574 :     bool        is_constraint = (indxinfo->indexconstraint != 0);
                              18252                 :                :     PQExpBuffer q;
                              18253                 :                :     PQExpBuffer delq;
                              18254                 :                :     char       *qindxname;
                              18255                 :                :     char       *qqindxname;
                              18256                 :                : 
                              18257                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18258         [ +  + ]:           2574 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       18259                 :            117 :         return;
                              18260                 :                : 
                              18261                 :           2457 :     q = createPQExpBuffer();
                              18262                 :           2457 :     delq = createPQExpBuffer();
                              18263                 :                : 
 2800                         18264                 :           2457 :     qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
 2056 alvherre@alvh.no-ip.    18265                 :           2457 :     qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
                              18266                 :                : 
                              18267                 :                :     /*
                              18268                 :                :      * If there's an associated constraint, don't dump the index per se, but
                              18269                 :                :      * do dump any comment for it.  (This is safe because dependency ordering
                              18270                 :                :      * will have ensured the constraint is emitted first.)  Note that the
                              18271                 :                :      * emitted comment has to be shown as depending on the constraint, not the
                              18272                 :                :      * index, in such cases.
                              18273                 :                :      */
 4505 tgl@sss.pgh.pa.us       18274         [ +  + ]:           2457 :     if (!is_constraint)
                              18275                 :                :     {
 2505 michael@paquier.xyz     18276                 :           1035 :         char       *indstatcols = indxinfo->indstatcols;
                              18277                 :           1035 :         char       *indstatvals = indxinfo->indstatvals;
                              18278                 :           1035 :         char      **indstatcolsarray = NULL;
                              18279                 :           1035 :         char      **indstatvalsarray = NULL;
 1803                         18280                 :           1035 :         int         nstatcols = 0;
                              18281                 :           1035 :         int         nstatvals = 0;
                              18282                 :                : 
 4031 alvherre@alvh.no-ip.    18283         [ +  + ]:           1035 :         if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    18284                 :            156 :             binary_upgrade_set_pg_class_oids(fout, q,
  481 nathan@postgresql.or    18285                 :            156 :                                              indxinfo->dobj.catId.oid);
                              18286                 :                : 
                              18287                 :                :         /* Plain secondary index */
 7996 tgl@sss.pgh.pa.us       18288                 :           1035 :         appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
                              18289                 :                : 
                              18290                 :                :         /*
                              18291                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              18292                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              18293                 :                :          * similar code in dumpConstraint!
                              18294                 :                :          */
                              18295                 :                : 
                              18296                 :                :         /* If the index is clustered, we need to record that. */
                              18297         [ -  + ]:           1035 :         if (indxinfo->indisclustered)
                              18298                 :                :         {
 7996 tgl@sss.pgh.pa.us       18299                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2800                         18300                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18301                 :                :             /* index name is not qualified in this syntax */
 7996                         18302                 :              0 :             appendPQExpBuffer(q, " ON %s;\n",
                              18303                 :                :                               qindxname);
                              18304                 :                :         }
                              18305                 :                : 
                              18306                 :                :         /*
                              18307                 :                :          * If the index has any statistics on some of its columns, generate
                              18308                 :                :          * the associated ALTER INDEX queries.
                              18309                 :                :          */
 1803 michael@paquier.xyz     18310   [ +  +  -  + ]:CBC        1035 :         if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
                              18311                 :                :         {
                              18312                 :                :             int         j;
                              18313                 :                : 
                              18314         [ -  + ]:             32 :             if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
 1298 tgl@sss.pgh.pa.us       18315                 :UBC           0 :                 pg_fatal("could not parse index statistic columns");
 1803 michael@paquier.xyz     18316         [ -  + ]:CBC          32 :             if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
 1298 tgl@sss.pgh.pa.us       18317                 :UBC           0 :                 pg_fatal("could not parse index statistic values");
 1803 michael@paquier.xyz     18318         [ -  + ]:CBC          32 :             if (nstatcols != nstatvals)
 1298 tgl@sss.pgh.pa.us       18319                 :UBC           0 :                 pg_fatal("mismatched number of columns and values for index statistics");
                              18320                 :                : 
 2505 michael@paquier.xyz     18321         [ +  + ]:CBC          96 :             for (j = 0; j < nstatcols; j++)
                              18322                 :                :             {
 2056 alvherre@alvh.no-ip.    18323                 :             64 :                 appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
                              18324                 :                : 
                              18325                 :                :                 /*
                              18326                 :                :                  * Note that this is a column number, so no quotes should be
                              18327                 :                :                  * used.
                              18328                 :                :                  */
 2505 michael@paquier.xyz     18329                 :             64 :                 appendPQExpBuffer(q, "ALTER COLUMN %s ",
                              18330                 :             64 :                                   indstatcolsarray[j]);
                              18331                 :             64 :                 appendPQExpBuffer(q, "SET STATISTICS %s;\n",
                              18332                 :             64 :                                   indstatvalsarray[j]);
                              18333                 :                :             }
                              18334                 :                :         }
                              18335                 :                : 
                              18336                 :                :         /* Indexes can depend on extensions */
 2056 alvherre@alvh.no-ip.    18337                 :           1035 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              18338                 :                :                                     "pg_catalog.pg_class",
                              18339                 :                :                                     "INDEX", qqindxname);
                              18340                 :                : 
                              18341                 :                :         /* If the index defines identity, we need to record that. */
 4371 rhaas@postgresql.org    18342         [ -  + ]:           1035 :         if (indxinfo->indisreplident)
                              18343                 :                :         {
 4371 rhaas@postgresql.org    18344                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
 2800 tgl@sss.pgh.pa.us       18345                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18346                 :                :             /* index name is not qualified in this syntax */
 4371 rhaas@postgresql.org    18347                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              18348                 :                :                               qindxname);
                              18349                 :                :         }
                              18350                 :                : 
                              18351                 :                :         /*
                              18352                 :                :          * If this index is a member of a partitioned index, the backend will
                              18353                 :                :          * not allow us to drop it separately, so don't try.  It will go away
                              18354                 :                :          * automatically when we drop either the index's table or the
                              18355                 :                :          * partitioned index.  (If, in a selective restore with --clean, we
                              18356                 :                :          * drop neither of those, then this index will not be dropped either.
                              18357                 :                :          * But that's fine, and even if you think it's not, the backend won't
                              18358                 :                :          * let us do differently.)
                              18359                 :                :          */
  194 tgl@sss.pgh.pa.us       18360         [ +  + ]:CBC        1035 :         if (indxinfo->parentidx == 0)
                              18361                 :            853 :             appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
                              18362                 :                : 
 3491 sfrost@snowman.net      18363         [ +  - ]:           1035 :         if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18364                 :           1035 :             ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18365                 :           1035 :                          ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
                              18366                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18367                 :                :                                       .tablespace = indxinfo->tablespace,
                              18368                 :                :                                       .owner = tbinfo->rolname,
                              18369                 :                :                                       .description = "INDEX",
                              18370                 :                :                                       .section = SECTION_POST_DATA,
                              18371                 :                :                                       .createStmt = q->data,
                              18372                 :                :                                       .dropStmt = delq->data));
                              18373                 :                : 
 1229 peter@eisentraut.org    18374                 :           1035 :         free(indstatcolsarray);
                              18375                 :           1035 :         free(indstatvalsarray);
                              18376                 :                :     }
                              18377                 :                : 
                              18378                 :                :     /* Dump Index Comments */
 3491 sfrost@snowman.net      18379         [ +  + ]:           2457 :     if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       18380         [ +  + ]:             15 :         dumpComment(fout, "INDEX", qindxname,
 3491 sfrost@snowman.net      18381                 :             15 :                     tbinfo->dobj.namespace->dobj.name,
                              18382                 :                :                     tbinfo->rolname,
                              18383                 :                :                     indxinfo->dobj.catId, 0,
                              18384                 :                :                     is_constraint ? indxinfo->indexconstraint :
                              18385                 :                :                     indxinfo->dobj.dumpId);
                              18386                 :                : 
 7996 tgl@sss.pgh.pa.us       18387                 :           2457 :     destroyPQExpBuffer(q);
                              18388                 :           2457 :     destroyPQExpBuffer(delq);
 2800                         18389                 :           2457 :     free(qindxname);
 2056 alvherre@alvh.no-ip.    18390                 :           2457 :     free(qqindxname);
                              18391                 :                : }
                              18392                 :                : 
                              18393                 :                : /*
                              18394                 :                :  * dumpIndexAttach
                              18395                 :                :  *    write out to fout a partitioned-index attachment clause
                              18396                 :                :  */
                              18397                 :                : static void
 1720 peter@eisentraut.org    18398                 :            564 : dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
                              18399                 :                : {
                              18400                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18401         [ +  + ]:            564 :     if (!fout->dopt->dumpSchema)
 2838 alvherre@alvh.no-ip.    18402                 :             48 :         return;
                              18403                 :                : 
                              18404         [ +  - ]:            516 :     if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18405                 :                :     {
 2835 tgl@sss.pgh.pa.us       18406                 :            516 :         PQExpBuffer q = createPQExpBuffer();
                              18407                 :                : 
 2617                         18408                 :            516 :         appendPQExpBuffer(q, "ALTER INDEX %s ",
 2800                         18409                 :            516 :                           fmtQualifiedDumpable(attachinfo->parentIdx));
 2838 alvherre@alvh.no-ip.    18410                 :            516 :         appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
 2800 tgl@sss.pgh.pa.us       18411                 :            516 :                           fmtQualifiedDumpable(attachinfo->partitionIdx));
                              18412                 :                : 
                              18413                 :                :         /*
                              18414                 :                :          * There is no need for a dropStmt since the drop is done implicitly
                              18415                 :                :          * when we drop either the index's table or the partitioned index.
                              18416                 :                :          * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
                              18417                 :                :          * there's no way to do it anyway.  (If you think to change this,
                              18418                 :                :          * consider also what to do with --if-exists.)
                              18419                 :                :          *
                              18420                 :                :          * Although this object doesn't really have ownership as such, set the
                              18421                 :                :          * owner field anyway to ensure that the command is run by the correct
                              18422                 :                :          * role at restore time.
                              18423                 :                :          */
 2838 alvherre@alvh.no-ip.    18424                 :            516 :         ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
 2460                         18425                 :            516 :                      ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              18426                 :                :                                   .namespace = attachinfo->dobj.namespace->dobj.name,
                              18427                 :                :                                   .owner = attachinfo->parentIdx->indextable->rolname,
                              18428                 :                :                                   .description = "INDEX ATTACH",
                              18429                 :                :                                   .section = SECTION_POST_DATA,
                              18430                 :                :                                   .createStmt = q->data));
                              18431                 :                : 
 2838                         18432                 :            516 :         destroyPQExpBuffer(q);
                              18433                 :                :     }
                              18434                 :                : }
                              18435                 :                : 
                              18436                 :                : /*
                              18437                 :                :  * dumpStatisticsExt
                              18438                 :                :  *    write out to fout an extended statistics object
                              18439                 :                :  */
                              18440                 :                : static void
 1720 peter@eisentraut.org    18441                 :            133 : dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
                              18442                 :                : {
 3139 alvherre@alvh.no-ip.    18443                 :            133 :     DumpOptions *dopt = fout->dopt;
                              18444                 :                :     PQExpBuffer q;
                              18445                 :                :     PQExpBuffer delq;
                              18446                 :                :     PQExpBuffer query;
                              18447                 :                :     char       *qstatsextname;
                              18448                 :                :     PGresult   *res;
                              18449                 :                :     char       *stxdef;
                              18450                 :                : 
                              18451                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18452         [ +  + ]:            133 :     if (!dopt->dumpSchema)
 3139 alvherre@alvh.no-ip.    18453                 :             18 :         return;
                              18454                 :                : 
                              18455                 :            115 :     q = createPQExpBuffer();
                              18456                 :            115 :     delq = createPQExpBuffer();
 2815 tgl@sss.pgh.pa.us       18457                 :            115 :     query = createPQExpBuffer();
                              18458                 :                : 
 2800                         18459                 :            115 :     qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
                              18460                 :                : 
 2815                         18461                 :            115 :     appendPQExpBuffer(query, "SELECT "
                              18462                 :                :                       "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
                              18463                 :            115 :                       statsextinfo->dobj.catId.oid);
                              18464                 :                : 
                              18465                 :            115 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              18466                 :                : 
                              18467                 :            115 :     stxdef = PQgetvalue(res, 0, 0);
                              18468                 :                : 
                              18469                 :                :     /* Result of pg_get_statisticsobjdef is complete except for semicolon */
                              18470                 :            115 :     appendPQExpBuffer(q, "%s;\n", stxdef);
                              18471                 :                : 
                              18472                 :                :     /*
                              18473                 :                :      * We only issue an ALTER STATISTICS statement if the stxstattarget entry
                              18474                 :                :      * for this statistics object is not the default value.
                              18475                 :                :      */
 2239 tomas.vondra@postgre    18476         [ +  + ]:            115 :     if (statsextinfo->stattarget >= 0)
                              18477                 :                :     {
                              18478                 :             32 :         appendPQExpBuffer(q, "ALTER STATISTICS %s ",
                              18479                 :             32 :                           fmtQualifiedDumpable(statsextinfo));
                              18480                 :             32 :         appendPQExpBuffer(q, "SET STATISTICS %d;\n",
                              18481                 :             32 :                           statsextinfo->stattarget);
                              18482                 :                :     }
                              18483                 :                : 
 2800 tgl@sss.pgh.pa.us       18484                 :            115 :     appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
                              18485                 :            115 :                       fmtQualifiedDumpable(statsextinfo));
                              18486                 :                : 
 3139 alvherre@alvh.no-ip.    18487         [ +  - ]:            115 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3085 bruce@momjian.us        18488                 :            115 :         ArchiveEntry(fout, statsextinfo->dobj.catId,
                              18489                 :            115 :                      statsextinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18490                 :            115 :                      ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
                              18491                 :                :                                   .namespace = statsextinfo->dobj.namespace->dobj.name,
                              18492                 :                :                                   .owner = statsextinfo->rolname,
                              18493                 :                :                                   .description = "STATISTICS",
                              18494                 :                :                                   .section = SECTION_POST_DATA,
                              18495                 :                :                                   .createStmt = q->data,
                              18496                 :                :                                   .dropStmt = delq->data));
                              18497                 :                : 
                              18498                 :                :     /* Dump Statistics Comments */
 3139                         18499         [ -  + ]:            115 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       18500                 :UBC           0 :         dumpComment(fout, "STATISTICS", qstatsextname,
 2815                         18501                 :              0 :                     statsextinfo->dobj.namespace->dobj.name,
                              18502                 :              0 :                     statsextinfo->rolname,
                              18503                 :                :                     statsextinfo->dobj.catId, 0,
 3139 alvherre@alvh.no-ip.    18504                 :              0 :                     statsextinfo->dobj.dumpId);
                              18505                 :                : 
 2815 tgl@sss.pgh.pa.us       18506                 :CBC         115 :     PQclear(res);
 3139 alvherre@alvh.no-ip.    18507                 :            115 :     destroyPQExpBuffer(q);
                              18508                 :            115 :     destroyPQExpBuffer(delq);
 2815 tgl@sss.pgh.pa.us       18509                 :            115 :     destroyPQExpBuffer(query);
 2800                         18510                 :            115 :     free(qstatsextname);
                              18511                 :                : }
                              18512                 :                : 
                              18513                 :                : /*
                              18514                 :                :  * dumpConstraint
                              18515                 :                :  *    write out to fout a user-defined constraint
                              18516                 :                :  */
                              18517                 :                : static void
 1720 peter@eisentraut.org    18518                 :           2473 : dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
                              18519                 :                : {
 3575 tgl@sss.pgh.pa.us       18520                 :           2473 :     DumpOptions *dopt = fout->dopt;
 7996                         18521                 :           2473 :     TableInfo  *tbinfo = coninfo->contable;
                              18522                 :                :     PQExpBuffer q;
                              18523                 :                :     PQExpBuffer delq;
 3532 peter_e@gmx.net         18524                 :           2473 :     char       *tag = NULL;
                              18525                 :                :     char       *foreign;
                              18526                 :                : 
                              18527                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    18528         [ +  + ]:           2473 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       18529                 :             98 :         return;
                              18530                 :                : 
                              18531                 :           2375 :     q = createPQExpBuffer();
                              18532                 :           2375 :     delq = createPQExpBuffer();
                              18533                 :                : 
 2047 alvherre@alvh.no-ip.    18534                 :           4596 :     foreign = tbinfo &&
 1992 tgl@sss.pgh.pa.us       18535   [ +  +  -  + ]:           2375 :         tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              18536                 :                : 
 5803                         18537         [ +  + ]:           2375 :     if (coninfo->contype == 'p' ||
                              18538         [ +  + ]:           1192 :         coninfo->contype == 'u' ||
                              18539         [ +  + ]:            963 :         coninfo->contype == 'x')
 7996                         18540                 :           1422 :     {
                              18541                 :                :         /* Index-related constraint */
                              18542                 :                :         IndxInfo   *indxinfo;
                              18543                 :                :         int         k;
                              18544                 :                : 
                              18545                 :           1422 :         indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
                              18546                 :                : 
                              18547         [ -  + ]:           1422 :         if (indxinfo == NULL)
 1298 tgl@sss.pgh.pa.us       18548                 :UBC           0 :             pg_fatal("missing index for constraint \"%s\"",
                              18549                 :                :                      coninfo->dobj.name);
                              18550                 :                : 
 4031 alvherre@alvh.no-ip.    18551         [ +  + ]:CBC        1422 :         if (dopt->binary_upgrade)
 5011 rhaas@postgresql.org    18552                 :            146 :             binary_upgrade_set_pg_class_oids(fout, q,
                              18553                 :                :                                              indxinfo->dobj.catId.oid);
                              18554                 :                : 
 2047 alvherre@alvh.no-ip.    18555                 :           1422 :         appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
 2800 tgl@sss.pgh.pa.us       18556                 :           1422 :                           fmtQualifiedDumpable(tbinfo));
 5803                         18557                 :           1422 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s ",
                              18558                 :           1422 :                           fmtId(coninfo->dobj.name));
                              18559                 :                : 
                              18560         [ +  + ]:           1422 :         if (coninfo->condef)
                              18561                 :                :         {
                              18562                 :                :             /* pg_get_constraintdef should have provided everything */
                              18563                 :             10 :             appendPQExpBuffer(q, "%s;\n", coninfo->condef);
                              18564                 :                :         }
                              18565                 :                :         else
                              18566                 :                :         {
 1147 drowley@postgresql.o    18567                 :           1412 :             appendPQExpBufferStr(q,
                              18568         [ +  + ]:           1412 :                                  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
                              18569                 :                : 
                              18570                 :                :             /*
                              18571                 :                :              * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
                              18572                 :                :              * indexes. Being able to create this was fixed, but we need to
                              18573                 :                :              * make the index distinct in order to be able to restore the
                              18574                 :                :              * dump.
                              18575                 :                :              */
  976 dgustafsson@postgres    18576   [ -  +  -  - ]:           1412 :             if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
 1147 drowley@postgresql.o    18577                 :UBC           0 :                 appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
 1147 drowley@postgresql.o    18578                 :CBC        1412 :             appendPQExpBufferStr(q, " (");
 2760 teodor@sigaev.ru        18579         [ +  + ]:           3411 :             for (k = 0; k < indxinfo->indnkeyattrs; k++)
                              18580                 :                :             {
 5803 tgl@sss.pgh.pa.us       18581                 :           1999 :                 int         indkey = (int) indxinfo->indkeys[k];
                              18582                 :                :                 const char *attname;
                              18583                 :                : 
                              18584         [ -  + ]:           1999 :                 if (indkey == InvalidAttrNumber)
 5803 tgl@sss.pgh.pa.us       18585                 :UBC           0 :                     break;
 5803 tgl@sss.pgh.pa.us       18586                 :CBC        1999 :                 attname = getAttrName(indkey, tbinfo);
                              18587                 :                : 
                              18588         [ +  + ]:           1999 :                 appendPQExpBuffer(q, "%s%s",
                              18589                 :                :                                   (k == 0) ? "" : ", ",
                              18590                 :                :                                   fmtId(attname));
                              18591                 :                :             }
  405 peter@eisentraut.org    18592         [ +  + ]:           1412 :             if (coninfo->conperiod)
                              18593                 :            104 :                 appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
                              18594                 :                : 
 2760 teodor@sigaev.ru        18595         [ +  + ]:           1412 :             if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
 2307 drowley@postgresql.o    18596                 :             20 :                 appendPQExpBufferStr(q, ") INCLUDE (");
                              18597                 :                : 
 2760 teodor@sigaev.ru        18598         [ +  + ]:           1452 :             for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
                              18599                 :                :             {
                              18600                 :             40 :                 int         indkey = (int) indxinfo->indkeys[k];
                              18601                 :                :                 const char *attname;
                              18602                 :                : 
                              18603         [ -  + ]:             40 :                 if (indkey == InvalidAttrNumber)
 2760 teodor@sigaev.ru        18604                 :UBC           0 :                     break;
 2760 teodor@sigaev.ru        18605                 :CBC          40 :                 attname = getAttrName(indkey, tbinfo);
                              18606                 :                : 
                              18607                 :             80 :                 appendPQExpBuffer(q, "%s%s",
                              18608         [ +  + ]:             40 :                                   (k == indxinfo->indnkeyattrs) ? "" : ", ",
                              18609                 :                :                                   fmtId(attname));
                              18610                 :                :             }
                              18611                 :                : 
 4361 heikki.linnakangas@i    18612                 :           1412 :             appendPQExpBufferChar(q, ')');
                              18613                 :                : 
 3586 tgl@sss.pgh.pa.us       18614         [ -  + ]:           1412 :             if (nonemptyReloptions(indxinfo->indreloptions))
                              18615                 :                :             {
 3586 tgl@sss.pgh.pa.us       18616                 :UBC           0 :                 appendPQExpBufferStr(q, " WITH (");
 3461 dean.a.rasheed@gmail    18617                 :              0 :                 appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
 3586 tgl@sss.pgh.pa.us       18618                 :              0 :                 appendPQExpBufferChar(q, ')');
                              18619                 :                :             }
                              18620                 :                : 
 5803 tgl@sss.pgh.pa.us       18621         [ +  + ]:CBC        1412 :             if (coninfo->condeferrable)
                              18622                 :                :             {
 4361 heikki.linnakangas@i    18623                 :             25 :                 appendPQExpBufferStr(q, " DEFERRABLE");
 5803 tgl@sss.pgh.pa.us       18624         [ +  + ]:             25 :                 if (coninfo->condeferred)
 4361 heikki.linnakangas@i    18625                 :             15 :                     appendPQExpBufferStr(q, " INITIALLY DEFERRED");
                              18626                 :                :             }
                              18627                 :                : 
                              18628                 :           1412 :             appendPQExpBufferStr(q, ";\n");
                              18629                 :                :         }
                              18630                 :                : 
                              18631                 :                :         /*
                              18632                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              18633                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              18634                 :                :          * similar code in dumpIndex!
                              18635                 :                :          */
                              18636                 :                : 
                              18637                 :                :         /* If the index is clustered, we need to record that. */
 7996 tgl@sss.pgh.pa.us       18638         [ +  + ]:           1422 :         if (indxinfo->indisclustered)
                              18639                 :                :         {
                              18640                 :             32 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2800                         18641                 :             32 :                               fmtQualifiedDumpable(tbinfo));
                              18642                 :                :             /* index name is not qualified in this syntax */
 7996                         18643                 :             32 :             appendPQExpBuffer(q, " ON %s;\n",
 7908                         18644                 :             32 :                               fmtId(indxinfo->dobj.name));
                              18645                 :                :         }
                              18646                 :                : 
                              18647                 :                :         /* If the index defines identity, we need to record that. */
 2646                         18648         [ -  + ]:           1422 :         if (indxinfo->indisreplident)
                              18649                 :                :         {
 2646 tgl@sss.pgh.pa.us       18650                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
                              18651                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18652                 :                :             /* index name is not qualified in this syntax */
                              18653                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              18654                 :              0 :                               fmtId(indxinfo->dobj.name));
                              18655                 :                :         }
                              18656                 :                : 
                              18657                 :                :         /* Indexes can depend on extensions */
 2056 alvherre@alvh.no-ip.    18658                 :CBC        1422 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              18659                 :                :                                     "pg_catalog.pg_class", "INDEX",
                              18660                 :           1422 :                                     fmtQualifiedDumpable(indxinfo));
                              18661                 :                : 
 2047                         18662                 :           1422 :         appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
 2800 tgl@sss.pgh.pa.us       18663                 :           1422 :                           fmtQualifiedDumpable(tbinfo));
 7996                         18664                 :           1422 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7908                         18665                 :           1422 :                           fmtId(coninfo->dobj.name));
                              18666                 :                : 
 3532 peter_e@gmx.net         18667                 :           1422 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18668                 :                : 
 3491 sfrost@snowman.net      18669         [ +  - ]:           1422 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18670                 :           1422 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18671                 :           1422 :                          ARCHIVE_OPTS(.tag = tag,
                              18672                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18673                 :                :                                       .tablespace = indxinfo->tablespace,
                              18674                 :                :                                       .owner = tbinfo->rolname,
                              18675                 :                :                                       .description = "CONSTRAINT",
                              18676                 :                :                                       .section = SECTION_POST_DATA,
                              18677                 :                :                                       .createStmt = q->data,
                              18678                 :                :                                       .dropStmt = delq->data));
                              18679                 :                :     }
 7996 tgl@sss.pgh.pa.us       18680         [ +  + ]:            953 :     else if (coninfo->contype == 'f')
                              18681                 :                :     {
                              18682                 :                :         char       *only;
                              18683                 :                : 
                              18684                 :                :         /*
                              18685                 :                :          * Foreign keys on partitioned tables are always declared as
                              18686                 :                :          * inheriting to partitions; for all other cases, emit them as
                              18687                 :                :          * applying ONLY directly to the named table, because that's how they
                              18688                 :                :          * work for regular inherited tables.
                              18689                 :                :          */
 2763 alvherre@alvh.no-ip.    18690         [ +  + ]:            159 :         only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
                              18691                 :                : 
                              18692                 :                :         /*
                              18693                 :                :          * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
                              18694                 :                :          * current table data is not processed
                              18695                 :                :          */
 2047                         18696                 :            159 :         appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
 2763                         18697                 :            159 :                           only, fmtQualifiedDumpable(tbinfo));
 7996 tgl@sss.pgh.pa.us       18698                 :            159 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7908                         18699                 :            159 :                           fmtId(coninfo->dobj.name),
 7996                         18700                 :            159 :                           coninfo->condef);
                              18701                 :                : 
 2047 alvherre@alvh.no-ip.    18702                 :            159 :         appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
 2763                         18703                 :            159 :                           only, fmtQualifiedDumpable(tbinfo));
 7996 tgl@sss.pgh.pa.us       18704                 :            159 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7908                         18705                 :            159 :                           fmtId(coninfo->dobj.name));
                              18706                 :                : 
 3532 peter_e@gmx.net         18707                 :            159 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18708                 :                : 
 3491 sfrost@snowman.net      18709         [ +  - ]:            159 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18710                 :            159 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18711                 :            159 :                          ARCHIVE_OPTS(.tag = tag,
                              18712                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18713                 :                :                                       .owner = tbinfo->rolname,
                              18714                 :                :                                       .description = "FK CONSTRAINT",
                              18715                 :                :                                       .section = SECTION_POST_DATA,
                              18716                 :                :                                       .createStmt = q->data,
                              18717                 :                :                                       .dropStmt = delq->data));
                              18718                 :                :     }
  203                         18719   [ +  +  +  -  :            794 :     else if ((coninfo->contype == 'c' || coninfo->contype == 'n') && tbinfo)
                                              +  + ]
                              18720                 :                :     {
                              18721                 :                :         /* CHECK or invalid not-null constraint on a table */
                              18722                 :                : 
                              18723                 :                :         /* Ignore if not to be dumped separately, or if it was inherited */
 3679 tgl@sss.pgh.pa.us       18724   [ +  +  +  + ]:            640 :         if (coninfo->separate && coninfo->conislocal)
                              18725                 :                :         {
                              18726                 :                :             const char *keyword;
                              18727                 :                : 
  203 alvherre@alvh.no-ip.    18728         [ +  + ]:            107 :             if (coninfo->contype == 'c')
                              18729                 :             45 :                 keyword = "CHECK CONSTRAINT";
                              18730                 :                :             else
                              18731                 :             62 :                 keyword = "CONSTRAINT";
                              18732                 :                : 
                              18733                 :                :             /* not ONLY since we want it to propagate to children */
 2047                         18734                 :            107 :             appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
 2800 tgl@sss.pgh.pa.us       18735                 :            107 :                               fmtQualifiedDumpable(tbinfo));
 7996                         18736                 :            107 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7908                         18737                 :            107 :                               fmtId(coninfo->dobj.name),
 7996                         18738                 :            107 :                               coninfo->condef);
                              18739                 :                : 
 2047 alvherre@alvh.no-ip.    18740                 :            107 :             appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
 2800 tgl@sss.pgh.pa.us       18741                 :            107 :                               fmtQualifiedDumpable(tbinfo));
 7996                         18742                 :            107 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7908                         18743                 :            107 :                               fmtId(coninfo->dobj.name));
                              18744                 :                : 
 3532 peter_e@gmx.net         18745                 :            107 :             tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18746                 :                : 
 3491 sfrost@snowman.net      18747         [ +  - ]:            107 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18748                 :            107 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18749                 :            107 :                              ARCHIVE_OPTS(.tag = tag,
                              18750                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              18751                 :                :                                           .owner = tbinfo->rolname,
                              18752                 :                :                                           .description = keyword,
                              18753                 :                :                                           .section = SECTION_POST_DATA,
                              18754                 :                :                                           .createStmt = q->data,
                              18755                 :                :                                           .dropStmt = delq->data));
                              18756                 :                :         }
                              18757                 :                :     }
   98 alvherre@kurilemu.de    18758         [ +  - ]:            154 :     else if (tbinfo == NULL)
                              18759                 :                :     {
                              18760                 :                :         /* CHECK, NOT NULL constraint on a domain */
 5787 bruce@momjian.us        18761                 :            154 :         TypeInfo   *tyinfo = coninfo->condomain;
                              18762                 :                : 
   98 alvherre@kurilemu.de    18763   [ +  +  -  + ]:            154 :         Assert(coninfo->contype == 'c' || coninfo->contype == 'n');
                              18764                 :                : 
                              18765                 :                :         /* Ignore if not to be dumped separately */
 7179 tgl@sss.pgh.pa.us       18766         [ +  + ]:            154 :         if (coninfo->separate)
                              18767                 :                :         {
                              18768                 :                :             const char *keyword;
                              18769                 :                : 
   98 alvherre@kurilemu.de    18770         [ +  - ]:              5 :             if (coninfo->contype == 'c')
                              18771                 :              5 :                 keyword = "CHECK CONSTRAINT";
                              18772                 :                :             else
   98 alvherre@kurilemu.de    18773                 :UBC           0 :                 keyword = "CONSTRAINT";
                              18774                 :                : 
 7996 tgl@sss.pgh.pa.us       18775                 :CBC           5 :             appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
 2800                         18776                 :              5 :                               fmtQualifiedDumpable(tyinfo));
 7996                         18777                 :              5 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7908                         18778                 :              5 :                               fmtId(coninfo->dobj.name),
 7996                         18779                 :              5 :                               coninfo->condef);
                              18780                 :                : 
 2800                         18781                 :              5 :             appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
                              18782                 :              5 :                               fmtQualifiedDumpable(tyinfo));
 7996                         18783                 :              5 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7908                         18784                 :              5 :                               fmtId(coninfo->dobj.name));
                              18785                 :                : 
 3532 peter_e@gmx.net         18786                 :              5 :             tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
                              18787                 :                : 
 3491 sfrost@snowman.net      18788         [ +  - ]:              5 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18789                 :              5 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    18790                 :              5 :                              ARCHIVE_OPTS(.tag = tag,
                              18791                 :                :                                           .namespace = tyinfo->dobj.namespace->dobj.name,
                              18792                 :                :                                           .owner = tyinfo->rolname,
                              18793                 :                :                                           .description = keyword,
                              18794                 :                :                                           .section = SECTION_POST_DATA,
                              18795                 :                :                                           .createStmt = q->data,
                              18796                 :                :                                           .dropStmt = delq->data));
                              18797                 :                : 
  103 alvherre@kurilemu.de    18798         [ +  - ]:              5 :             if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              18799                 :                :             {
                              18800                 :              5 :                 PQExpBuffer conprefix = createPQExpBuffer();
                              18801                 :              5 :                 char       *qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
                              18802                 :                : 
                              18803                 :              5 :                 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
                              18804                 :              5 :                                   fmtId(coninfo->dobj.name));
                              18805                 :                : 
                              18806                 :              5 :                 dumpComment(fout, conprefix->data, qtypname,
                              18807                 :              5 :                             tyinfo->dobj.namespace->dobj.name,
                              18808                 :                :                             tyinfo->rolname,
   41 noah@leadboat.com       18809                 :              5 :                             coninfo->dobj.catId, 0, coninfo->dobj.dumpId);
  103 alvherre@kurilemu.de    18810                 :              5 :                 destroyPQExpBuffer(conprefix);
                              18811                 :              5 :                 free(qtypname);
                              18812                 :                :             }
                              18813                 :                :         }
                              18814                 :                :     }
                              18815                 :                :     else
                              18816                 :                :     {
 1298 tgl@sss.pgh.pa.us       18817                 :UBC           0 :         pg_fatal("unrecognized constraint type: %c",
                              18818                 :                :                  coninfo->contype);
                              18819                 :                :     }
                              18820                 :                : 
                              18821                 :                :     /* Dump Constraint Comments --- only works for table constraints */
 3491 sfrost@snowman.net      18822   [ +  +  +  + ]:CBC        2375 :     if (tbinfo && coninfo->separate &&
                              18823         [ +  + ]:           1718 :         coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 3575 tgl@sss.pgh.pa.us       18824                 :             47 :         dumpTableConstraintComment(fout, coninfo);
                              18825                 :                : 
 3532 peter_e@gmx.net         18826                 :           2375 :     free(tag);
 8571 tgl@sss.pgh.pa.us       18827                 :           2375 :     destroyPQExpBuffer(q);
                              18828                 :           2375 :     destroyPQExpBuffer(delq);
                              18829                 :                : }
                              18830                 :                : 
                              18831                 :                : /*
                              18832                 :                :  * dumpTableConstraintComment --- dump a constraint's comment if any
                              18833                 :                :  *
                              18834                 :                :  * This is split out because we need the function in two different places
                              18835                 :                :  * depending on whether the constraint is dumped as part of CREATE TABLE
                              18836                 :                :  * or as a separate ALTER command.
                              18837                 :                :  */
                              18838                 :                : static void
 1720 peter@eisentraut.org    18839                 :             84 : dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
                              18840                 :                : {
 7622 tgl@sss.pgh.pa.us       18841                 :             84 :     TableInfo  *tbinfo = coninfo->contable;
 2800                         18842                 :             84 :     PQExpBuffer conprefix = createPQExpBuffer();
                              18843                 :                :     char       *qtabname;
                              18844                 :                : 
                              18845                 :             84 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              18846                 :                : 
                              18847                 :             84 :     appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
 7622                         18848                 :             84 :                       fmtId(coninfo->dobj.name));
                              18849                 :                : 
 3491 sfrost@snowman.net      18850         [ +  - ]:             84 :     if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       18851                 :             84 :         dumpComment(fout, conprefix->data, qtabname,
 3491 sfrost@snowman.net      18852                 :             84 :                     tbinfo->dobj.namespace->dobj.name,
                              18853                 :                :                     tbinfo->rolname,
                              18854                 :                :                     coninfo->dobj.catId, 0,
 3050 tgl@sss.pgh.pa.us       18855         [ +  + ]:             84 :                     coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
                              18856                 :                : 
 2800                         18857                 :             84 :     destroyPQExpBuffer(conprefix);
                              18858                 :             84 :     free(qtabname);
 7622                         18859                 :             84 : }
                              18860                 :                : 
                              18861                 :                : static inline SeqType
  453 nathan@postgresql.or    18862                 :            638 : parse_sequence_type(const char *name)
                              18863                 :                : {
                              18864         [ +  - ]:           1425 :     for (int i = 0; i < lengthof(SeqTypeNames); i++)
                              18865                 :                :     {
                              18866         [ +  + ]:           1425 :         if (strcmp(SeqTypeNames[i], name) == 0)
                              18867                 :            638 :             return (SeqType) i;
                              18868                 :                :     }
                              18869                 :                : 
  453 nathan@postgresql.or    18870                 :UBC           0 :     pg_fatal("unrecognized sequence type: %s", name);
                              18871                 :                :     return (SeqType) 0;         /* keep compiler quiet */
                              18872                 :                : }
                              18873                 :                : 
                              18874                 :                : /*
                              18875                 :                :  * bsearch() comparator for SequenceItem
                              18876                 :                :  */
                              18877                 :                : static int
  453 nathan@postgresql.or    18878                 :CBC        2954 : SequenceItemCmp(const void *p1, const void *p2)
                              18879                 :                : {
                              18880                 :           2954 :     SequenceItem v1 = *((const SequenceItem *) p1);
                              18881                 :           2954 :     SequenceItem v2 = *((const SequenceItem *) p2);
                              18882                 :                : 
                              18883                 :           2954 :     return pg_cmp_u32(v1.oid, v2.oid);
                              18884                 :                : }
                              18885                 :                : 
                              18886                 :                : /*
                              18887                 :                :  * collectSequences
                              18888                 :                :  *
                              18889                 :                :  * Construct a table of sequence information.  This table is sorted by OID for
                              18890                 :                :  * speed in lookup.
                              18891                 :                :  */
                              18892                 :                : static void
                              18893                 :            189 : collectSequences(Archive *fout)
                              18894                 :                : {
                              18895                 :                :     PGresult   *res;
                              18896                 :                :     const char *query;
                              18897                 :                : 
                              18898                 :                :     /*
                              18899                 :                :      * Before Postgres 10, sequence metadata is in the sequence itself.  With
                              18900                 :                :      * some extra effort, we might be able to use the sorted table for those
                              18901                 :                :      * versions, but for now it seems unlikely to be worth it.
                              18902                 :                :      *
                              18903                 :                :      * Since version 18, we can gather the sequence data in this query with
                              18904                 :                :      * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
                              18905                 :                :      */
                              18906         [ -  + ]:            189 :     if (fout->remoteVersion < 100000)
  453 nathan@postgresql.or    18907                 :UBC           0 :         return;
  453 nathan@postgresql.or    18908         [ +  - ]:CBC         189 :     else if (fout->remoteVersion < 180000 ||
  336                         18909   [ +  +  +  + ]:            189 :              (!fout->dopt->dumpData && !fout->dopt->sequence_data))
  453                         18910                 :              8 :         query = "SELECT seqrelid, format_type(seqtypid, NULL), "
                              18911                 :                :             "seqstart, seqincrement, "
                              18912                 :                :             "seqmax, seqmin, "
                              18913                 :                :             "seqcache, seqcycle, "
                              18914                 :                :             "NULL, 'f' "
                              18915                 :                :             "FROM pg_catalog.pg_sequence "
                              18916                 :                :             "ORDER BY seqrelid";
                              18917                 :                :     else
                              18918                 :            181 :         query = "SELECT seqrelid, format_type(seqtypid, NULL), "
                              18919                 :                :             "seqstart, seqincrement, "
                              18920                 :                :             "seqmax, seqmin, "
                              18921                 :                :             "seqcache, seqcycle, "
                              18922                 :                :             "last_value, is_called "
                              18923                 :                :             "FROM pg_catalog.pg_sequence, "
                              18924                 :                :             "pg_get_sequence_data(seqrelid) "
                              18925                 :                :             "ORDER BY seqrelid;";
                              18926                 :                : 
                              18927                 :            189 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                              18928                 :                : 
                              18929                 :            189 :     nsequences = PQntuples(res);
                              18930                 :            189 :     sequences = (SequenceItem *) pg_malloc(nsequences * sizeof(SequenceItem));
                              18931                 :                : 
                              18932         [ +  + ]:            827 :     for (int i = 0; i < nsequences; i++)
                              18933                 :                :     {
                              18934                 :            638 :         sequences[i].oid = atooid(PQgetvalue(res, i, 0));
                              18935                 :            638 :         sequences[i].seqtype = parse_sequence_type(PQgetvalue(res, i, 1));
                              18936                 :            638 :         sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
                              18937                 :            638 :         sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
                              18938                 :            638 :         sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
                              18939                 :            638 :         sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
                              18940                 :            638 :         sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
                              18941                 :            638 :         sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
                              18942                 :            638 :         sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
                              18943                 :            638 :         sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
                              18944                 :                :     }
                              18945                 :                : 
                              18946                 :            189 :     PQclear(res);
                              18947                 :                : }
                              18948                 :                : 
                              18949                 :                : /*
                              18950                 :                :  * dumpSequence
                              18951                 :                :  *    write the declaration (not data) of one user-defined sequence
                              18952                 :                :  */
                              18953                 :                : static void
 1720 peter@eisentraut.org    18954                 :            375 : dumpSequence(Archive *fout, const TableInfo *tbinfo)
                              18955                 :                : {
 3575 tgl@sss.pgh.pa.us       18956                 :            375 :     DumpOptions *dopt = fout->dopt;
                              18957                 :                :     SequenceItem *seq;
                              18958                 :                :     bool        is_ascending;
                              18959                 :                :     int64       default_minv,
                              18960                 :                :                 default_maxv;
 9329 bruce@momjian.us        18961                 :            375 :     PQExpBuffer query = createPQExpBuffer();
 9246                         18962                 :            375 :     PQExpBuffer delqry = createPQExpBuffer();
                              18963                 :                :     char       *qseqname;
 1299 peter@eisentraut.org    18964                 :            375 :     TableInfo  *owning_tab = NULL;
                              18965                 :                : 
 2800 tgl@sss.pgh.pa.us       18966                 :            375 :     qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
                              18967                 :                : 
                              18968                 :                :     /*
                              18969                 :                :      * For versions >= 10, the sequence information is gathered in a sorted
                              18970                 :                :      * table before any calls to dumpSequence().  See collectSequences() for
                              18971                 :                :      * more information.
                              18972                 :                :      */
 3233 peter_e@gmx.net         18973         [ +  - ]:            375 :     if (fout->remoteVersion >= 100000)
                              18974                 :                :     {
  453 nathan@postgresql.or    18975                 :            375 :         SequenceItem key = {0};
                              18976                 :                : 
                              18977         [ -  + ]:            375 :         Assert(sequences);
                              18978                 :                : 
                              18979                 :            375 :         key.oid = tbinfo->dobj.catId.oid;
                              18980                 :            375 :         seq = bsearch(&key, sequences, nsequences,
                              18981                 :                :                       sizeof(SequenceItem), SequenceItemCmp);
                              18982                 :                :     }
                              18983                 :                :     else
                              18984                 :                :     {
                              18985                 :                :         PGresult   *res;
                              18986                 :                : 
                              18987                 :                :         /*
                              18988                 :                :          * Before PostgreSQL 10, sequence metadata is in the sequence itself.
                              18989                 :                :          *
                              18990                 :                :          * Note: it might seem that 'bigint' potentially needs to be
                              18991                 :                :          * schema-qualified, but actually that's a keyword.
                              18992                 :                :          */
 6373 tgl@sss.pgh.pa.us       18993                 :UBC           0 :         appendPQExpBuffer(query,
                              18994                 :                :                           "SELECT 'bigint' AS sequence_type, "
                              18995                 :                :                           "start_value, increment_by, max_value, min_value, "
                              18996                 :                :                           "cache_value, is_cycled FROM %s",
 2800                         18997                 :              0 :                           fmtQualifiedDumpable(tbinfo));
                              18998                 :                : 
  453 nathan@postgresql.or    18999                 :              0 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19000                 :                : 
                              19001         [ #  # ]:              0 :         if (PQntuples(res) != 1)
                              19002                 :              0 :             pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              19003                 :                :                               "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              19004                 :                :                               PQntuples(res)),
                              19005                 :                :                      tbinfo->dobj.name, PQntuples(res));
                              19006                 :                : 
                              19007                 :              0 :         seq = pg_malloc0(sizeof(SequenceItem));
                              19008                 :              0 :         seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
                              19009                 :              0 :         seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
                              19010                 :              0 :         seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
                              19011                 :              0 :         seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
                              19012                 :              0 :         seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
                              19013                 :              0 :         seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
                              19014                 :              0 :         seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
                              19015                 :                : 
                              19016                 :              0 :         PQclear(res);
                              19017                 :                :     }
                              19018                 :                : 
                              19019                 :                :     /* Calculate default limits for a sequence of this type */
  453 nathan@postgresql.or    19020                 :CBC         375 :     is_ascending = (seq->incby >= 0);
                              19021         [ +  + ]:            375 :     if (seq->seqtype == SEQTYPE_SMALLINT)
                              19022                 :                :     {
 2806 tgl@sss.pgh.pa.us       19023         [ +  + ]:             25 :         default_minv = is_ascending ? 1 : PG_INT16_MIN;
                              19024         [ +  + ]:             25 :         default_maxv = is_ascending ? PG_INT16_MAX : -1;
                              19025                 :                :     }
  453 nathan@postgresql.or    19026         [ +  + ]:            350 :     else if (seq->seqtype == SEQTYPE_INTEGER)
                              19027                 :                :     {
 2806 tgl@sss.pgh.pa.us       19028         [ +  + ]:            284 :         default_minv = is_ascending ? 1 : PG_INT32_MIN;
                              19029         [ +  + ]:            284 :         default_maxv = is_ascending ? PG_INT32_MAX : -1;
                              19030                 :                :     }
  453 nathan@postgresql.or    19031         [ +  - ]:             66 :     else if (seq->seqtype == SEQTYPE_BIGINT)
                              19032                 :                :     {
 2806 tgl@sss.pgh.pa.us       19033         [ +  + ]:             66 :         default_minv = is_ascending ? 1 : PG_INT64_MIN;
                              19034         [ +  + ]:             66 :         default_maxv = is_ascending ? PG_INT64_MAX : -1;
                              19035                 :                :     }
                              19036                 :                :     else
                              19037                 :                :     {
  453 nathan@postgresql.or    19038                 :UBC           0 :         pg_fatal("unrecognized sequence type: %d", seq->seqtype);
                              19039                 :                :         default_minv = default_maxv = 0;    /* keep compiler quiet */
                              19040                 :                :     }
                              19041                 :                : 
                              19042                 :                :     /*
                              19043                 :                :      * Identity sequences are not to be dropped separately.
                              19044                 :                :      */
 3126 peter_e@gmx.net         19045         [ +  + ]:CBC         375 :     if (!tbinfo->is_identity_sequence)
                              19046                 :                :     {
 2800 tgl@sss.pgh.pa.us       19047                 :            233 :         appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
                              19048                 :            233 :                           fmtQualifiedDumpable(tbinfo));
                              19049                 :                :     }
                              19050                 :                : 
 4749                         19051                 :            375 :     resetPQExpBuffer(query);
                              19052                 :                : 
 4031 alvherre@alvh.no-ip.    19053         [ +  + ]:            375 :     if (dopt->binary_upgrade)
                              19054                 :                :     {
 4749 tgl@sss.pgh.pa.us       19055                 :             66 :         binary_upgrade_set_pg_class_oids(fout, query,
  481 nathan@postgresql.or    19056                 :             66 :                                          tbinfo->dobj.catId.oid);
                              19057                 :                : 
                              19058                 :                :         /*
                              19059                 :                :          * In older PG versions a sequence will have a pg_type entry, but v14
                              19060                 :                :          * and up don't use that, so don't attempt to preserve the type OID.
                              19061                 :                :          */
                              19062                 :                :     }
                              19063                 :                : 
 3126 peter_e@gmx.net         19064         [ +  + ]:            375 :     if (tbinfo->is_identity_sequence)
                              19065                 :                :     {
 1299 peter@eisentraut.org    19066                 :            142 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              19067                 :                : 
 3126 peter_e@gmx.net         19068                 :            142 :         appendPQExpBuffer(query,
                              19069                 :                :                           "ALTER TABLE %s ",
 2800 tgl@sss.pgh.pa.us       19070                 :            142 :                           fmtQualifiedDumpable(owning_tab));
 3126 peter_e@gmx.net         19071                 :            142 :         appendPQExpBuffer(query,
                              19072                 :                :                           "ALTER COLUMN %s ADD GENERATED ",
 3050 tgl@sss.pgh.pa.us       19073                 :            142 :                           fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
 3126 peter_e@gmx.net         19074         [ +  + ]:            142 :         if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
 2307 drowley@postgresql.o    19075                 :            102 :             appendPQExpBufferStr(query, "ALWAYS");
 3126 peter_e@gmx.net         19076         [ +  - ]:             40 :         else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
 2307 drowley@postgresql.o    19077                 :             40 :             appendPQExpBufferStr(query, "BY DEFAULT");
 3126 peter_e@gmx.net         19078                 :            142 :         appendPQExpBuffer(query, " AS IDENTITY (\n    SEQUENCE NAME %s\n",
 2800 tgl@sss.pgh.pa.us       19079                 :            142 :                           fmtQualifiedDumpable(tbinfo));
                              19080                 :                : 
                              19081                 :                :         /*
                              19082                 :                :          * Emit persistence option only if it's different from the owning
                              19083                 :                :          * table's.  This avoids using this new syntax unnecessarily.
                              19084                 :                :          */
  405                         19085         [ +  + ]:            142 :         if (tbinfo->relpersistence != owning_tab->relpersistence)
                              19086                 :             10 :             appendPQExpBuffer(query, "    %s\n",
                              19087         [ +  + ]:             10 :                               tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              19088                 :                :                               "UNLOGGED" : "LOGGED");
                              19089                 :                :     }
                              19090                 :                :     else
                              19091                 :                :     {
 3126 peter_e@gmx.net         19092                 :            233 :         appendPQExpBuffer(query,
                              19093                 :                :                           "CREATE %sSEQUENCE %s\n",
 1299 peter@eisentraut.org    19094         [ +  + ]:            233 :                           tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              19095                 :                :                           "UNLOGGED " : "",
 2800 tgl@sss.pgh.pa.us       19096                 :            233 :                           fmtQualifiedDumpable(tbinfo));
                              19097                 :                : 
  453 nathan@postgresql.or    19098         [ +  + ]:            233 :         if (seq->seqtype != SEQTYPE_BIGINT)
                              19099                 :            182 :             appendPQExpBuffer(query, "    AS %s\n", SeqTypeNames[seq->seqtype]);
                              19100                 :                :     }
                              19101                 :                : 
                              19102                 :            375 :     appendPQExpBuffer(query, "    START WITH " INT64_FORMAT "\n", seq->startv);
                              19103                 :                : 
                              19104                 :            375 :     appendPQExpBuffer(query, "    INCREMENT BY " INT64_FORMAT "\n", seq->incby);
                              19105                 :                : 
                              19106         [ +  + ]:            375 :     if (seq->minv != default_minv)
                              19107                 :             15 :         appendPQExpBuffer(query, "    MINVALUE " INT64_FORMAT "\n", seq->minv);
                              19108                 :                :     else
 4361 heikki.linnakangas@i    19109                 :            360 :         appendPQExpBufferStr(query, "    NO MINVALUE\n");
                              19110                 :                : 
  453 nathan@postgresql.or    19111         [ +  + ]:            375 :     if (seq->maxv != default_maxv)
                              19112                 :             15 :         appendPQExpBuffer(query, "    MAXVALUE " INT64_FORMAT "\n", seq->maxv);
                              19113                 :                :     else
 4361 heikki.linnakangas@i    19114                 :            360 :         appendPQExpBufferStr(query, "    NO MAXVALUE\n");
                              19115                 :                : 
 4749 tgl@sss.pgh.pa.us       19116                 :            375 :     appendPQExpBuffer(query,
                              19117                 :                :                       "    CACHE " INT64_FORMAT "%s",
  453 nathan@postgresql.or    19118         [ +  + ]:            375 :                       seq->cache, (seq->cycled ? "\n    CYCLE" : ""));
                              19119                 :                : 
 3126 peter_e@gmx.net         19120         [ +  + ]:            375 :     if (tbinfo->is_identity_sequence)
                              19121                 :            142 :         appendPQExpBufferStr(query, "\n);\n");
                              19122                 :                :     else
                              19123                 :            233 :         appendPQExpBufferStr(query, ";\n");
                              19124                 :                : 
                              19125                 :                :     /* binary_upgrade:  no need to clear TOAST table oid */
                              19126                 :                : 
 4031 alvherre@alvh.no-ip.    19127         [ +  + ]:            375 :     if (dopt->binary_upgrade)
 4749 tgl@sss.pgh.pa.us       19128                 :             66 :         binary_upgrade_extension_member(query, &tbinfo->dobj,
                              19129                 :                :                                         "SEQUENCE", qseqname,
 2800                         19130                 :             66 :                                         tbinfo->dobj.namespace->dobj.name);
                              19131                 :                : 
 3491 sfrost@snowman.net      19132         [ +  - ]:            375 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19133                 :            375 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    19134                 :            375 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19135                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19136                 :                :                                   .owner = tbinfo->rolname,
                              19137                 :                :                                   .description = "SEQUENCE",
                              19138                 :                :                                   .section = SECTION_PRE_DATA,
                              19139                 :                :                                   .createStmt = query->data,
                              19140                 :                :                                   .dropStmt = delqry->data));
                              19141                 :                : 
                              19142                 :                :     /*
                              19143                 :                :      * If the sequence is owned by a table column, emit the ALTER for it as a
                              19144                 :                :      * separate TOC entry immediately following the sequence's own entry. It's
                              19145                 :                :      * OK to do this rather than using full sorting logic, because the
                              19146                 :                :      * dependency that tells us it's owned will have forced the table to be
                              19147                 :                :      * created first.  We can't just include the ALTER in the TOC entry
                              19148                 :                :      * because it will fail if we haven't reassigned the sequence owner to
                              19149                 :                :      * match the table's owner.
                              19150                 :                :      *
                              19151                 :                :      * We need not schema-qualify the table reference because both sequence
                              19152                 :                :      * and table must be in the same schema.
                              19153                 :                :      */
 3126 peter_e@gmx.net         19154   [ +  +  +  + ]:            375 :     if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
                              19155                 :                :     {
 1164 drowley@postgresql.o    19156                 :            137 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              19157                 :                : 
 3216 sfrost@snowman.net      19158         [ -  + ]:            137 :         if (owning_tab == NULL)
 1298 tgl@sss.pgh.pa.us       19159                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                              19160                 :                :                      tbinfo->owning_tab, tbinfo->dobj.catId.oid);
                              19161                 :                : 
 3216 sfrost@snowman.net      19162         [ +  + ]:CBC         137 :         if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19163                 :                :         {
 4749 tgl@sss.pgh.pa.us       19164                 :            135 :             resetPQExpBuffer(query);
                              19165                 :            135 :             appendPQExpBuffer(query, "ALTER SEQUENCE %s",
 2800                         19166                 :            135 :                               fmtQualifiedDumpable(tbinfo));
 4749                         19167                 :            135 :             appendPQExpBuffer(query, " OWNED BY %s",
 2800                         19168                 :            135 :                               fmtQualifiedDumpable(owning_tab));
 4749                         19169                 :            135 :             appendPQExpBuffer(query, ".%s;\n",
 3050                         19170                 :            135 :                               fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
                              19171                 :                : 
 3491 sfrost@snowman.net      19172         [ +  - ]:            135 :             if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19173                 :            135 :                 ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    19174                 :            135 :                              ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19175                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              19176                 :                :                                           .owner = tbinfo->rolname,
                              19177                 :                :                                           .description = "SEQUENCE OWNED BY",
                              19178                 :                :                                           .section = SECTION_PRE_DATA,
                              19179                 :                :                                           .createStmt = query->data,
                              19180                 :                :                                           .deps = &(tbinfo->dobj.dumpId),
                              19181                 :                :                                           .nDeps = 1));
                              19182                 :                :         }
                              19183                 :                :     }
                              19184                 :                : 
                              19185                 :                :     /* Dump Sequence Comments and Security Labels */
 3491 sfrost@snowman.net      19186         [ -  + ]:            375 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       19187                 :UBC           0 :         dumpComment(fout, "SEQUENCE", qseqname,
 3491 sfrost@snowman.net      19188                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19189                 :              0 :                     tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              19190                 :                : 
 3491 sfrost@snowman.net      19191         [ -  + ]:CBC         375 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2800 tgl@sss.pgh.pa.us       19192                 :UBC           0 :         dumpSecLabel(fout, "SEQUENCE", qseqname,
 3491 sfrost@snowman.net      19193                 :              0 :                      tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19194                 :              0 :                      tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              19195                 :                : 
  453 nathan@postgresql.or    19196         [ -  + ]:CBC         375 :     if (fout->remoteVersion < 100000)
  453 nathan@postgresql.or    19197                 :UBC           0 :         pg_free(seq);
 8851 tgl@sss.pgh.pa.us       19198                 :CBC         375 :     destroyPQExpBuffer(query);
                              19199                 :            375 :     destroyPQExpBuffer(delqry);
 2800                         19200                 :            375 :     free(qseqname);
10435 vadim4o@yahoo.com       19201                 :            375 : }
                              19202                 :                : 
                              19203                 :                : /*
                              19204                 :                :  * dumpSequenceData
                              19205                 :                :  *    write the data of one user-defined sequence
                              19206                 :                :  */
                              19207                 :                : static void
 1720 peter@eisentraut.org    19208                 :            393 : dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
                              19209                 :                : {
 4749 tgl@sss.pgh.pa.us       19210                 :            393 :     TableInfo  *tbinfo = tdinfo->tdtable;
                              19211                 :                :     int64       last;
                              19212                 :                :     bool        called;
                              19213                 :            393 :     PQExpBuffer query = createPQExpBuffer();
                              19214                 :                : 
                              19215                 :                :     /*
                              19216                 :                :      * For versions >= 18, the sequence information is gathered in the sorted
                              19217                 :                :      * array before any calls to dumpSequenceData().  See collectSequences()
                              19218                 :                :      * for more information.
                              19219                 :                :      *
                              19220                 :                :      * For older versions, we have to query the sequence relations
                              19221                 :                :      * individually.
                              19222                 :                :      */
  453 nathan@postgresql.or    19223         [ -  + ]:            393 :     if (fout->remoteVersion < 180000)
                              19224                 :                :     {
                              19225                 :                :         PGresult   *res;
                              19226                 :                : 
  453 nathan@postgresql.or    19227                 :UBC           0 :         appendPQExpBuffer(query,
                              19228                 :                :                           "SELECT last_value, is_called FROM %s",
                              19229                 :              0 :                           fmtQualifiedDumpable(tbinfo));
                              19230                 :                : 
                              19231                 :              0 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19232                 :                : 
                              19233         [ #  # ]:              0 :         if (PQntuples(res) != 1)
                              19234                 :              0 :             pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              19235                 :                :                               "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              19236                 :                :                               PQntuples(res)),
                              19237                 :                :                      tbinfo->dobj.name, PQntuples(res));
                              19238                 :                : 
                              19239                 :              0 :         last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
                              19240                 :              0 :         called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
                              19241                 :                : 
                              19242                 :              0 :         PQclear(res);
                              19243                 :                :     }
                              19244                 :                :     else
                              19245                 :                :     {
  453 nathan@postgresql.or    19246                 :CBC         393 :         SequenceItem key = {0};
                              19247                 :                :         SequenceItem *entry;
                              19248                 :                : 
                              19249         [ -  + ]:            393 :         Assert(sequences);
                              19250         [ -  + ]:            393 :         Assert(tbinfo->dobj.catId.oid);
                              19251                 :                : 
                              19252                 :            393 :         key.oid = tbinfo->dobj.catId.oid;
                              19253                 :            393 :         entry = bsearch(&key, sequences, nsequences,
                              19254                 :                :                         sizeof(SequenceItem), SequenceItemCmp);
                              19255                 :                : 
                              19256                 :            393 :         last = entry->last_value;
                              19257                 :            393 :         called = entry->is_called;
                              19258                 :                :     }
                              19259                 :                : 
 4749 tgl@sss.pgh.pa.us       19260                 :            393 :     resetPQExpBuffer(query);
 4361 heikki.linnakangas@i    19261                 :            393 :     appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
 2800 tgl@sss.pgh.pa.us       19262                 :            393 :     appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
  453 nathan@postgresql.or    19263         [ +  + ]:            393 :     appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
                              19264                 :                :                       last, (called ? "true" : "false"));
                              19265                 :                : 
 3203 sfrost@snowman.net      19266         [ +  - ]:            393 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
 3491                         19267                 :            393 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2460 alvherre@alvh.no-ip.    19268                 :            393 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19269                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19270                 :                :                                   .owner = tbinfo->rolname,
                              19271                 :                :                                   .description = "SEQUENCE SET",
                              19272                 :                :                                   .section = SECTION_DATA,
                              19273                 :                :                                   .createStmt = query->data,
                              19274                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              19275                 :                :                                   .nDeps = 1));
                              19276                 :                : 
 4749 tgl@sss.pgh.pa.us       19277                 :            393 :     destroyPQExpBuffer(query);
                              19278                 :            393 : }
                              19279                 :                : 
                              19280                 :                : /*
                              19281                 :                :  * dumpTrigger
                              19282                 :                :  *    write the declaration of one user-defined table trigger
                              19283                 :                :  */
                              19284                 :                : static void
 1720 peter@eisentraut.org    19285                 :            523 : dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
                              19286                 :                : {
 3575 tgl@sss.pgh.pa.us       19287                 :            523 :     DumpOptions *dopt = fout->dopt;
 7996                         19288                 :            523 :     TableInfo  *tbinfo = tginfo->tgtable;
                              19289                 :                :     PQExpBuffer query;
                              19290                 :                :     PQExpBuffer delqry;
                              19291                 :                :     PQExpBuffer trigprefix;
                              19292                 :                :     PQExpBuffer trigidentity;
                              19293                 :                :     char       *qtabname;
                              19294                 :                :     char       *tag;
                              19295                 :                : 
                              19296                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    19297         [ +  + ]:            523 :     if (!dopt->dumpSchema)
 8473 tgl@sss.pgh.pa.us       19298                 :             31 :         return;
                              19299                 :                : 
 7996                         19300                 :            492 :     query = createPQExpBuffer();
                              19301                 :            492 :     delqry = createPQExpBuffer();
 2800                         19302                 :            492 :     trigprefix = createPQExpBuffer();
 2056 alvherre@alvh.no-ip.    19303                 :            492 :     trigidentity = createPQExpBuffer();
                              19304                 :                : 
 2800 tgl@sss.pgh.pa.us       19305                 :            492 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              19306                 :                : 
 2056 alvherre@alvh.no-ip.    19307                 :            492 :     appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
                              19308                 :            492 :     appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
                              19309                 :                : 
  652 peter@eisentraut.org    19310                 :            492 :     appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
 2056 alvherre@alvh.no-ip.    19311                 :            492 :     appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
                              19312                 :                : 
                              19313                 :                :     /* Triggers can depend on extensions */
                              19314                 :            492 :     append_depends_on_extension(fout, query, &tginfo->dobj,
                              19315                 :                :                                 "pg_catalog.pg_trigger", "TRIGGER",
                              19316                 :            492 :                                 trigidentity->data);
                              19317                 :                : 
 1391                         19318         [ +  + ]:            492 :     if (tginfo->tgispartition)
                              19319                 :                :     {
                              19320         [ -  + ]:            109 :         Assert(tbinfo->ispartition);
                              19321                 :                : 
                              19322                 :                :         /*
                              19323                 :                :          * Partition triggers only appear here because their 'tgenabled' flag
                              19324                 :                :          * differs from its parent's.  The trigger is created already, so
                              19325                 :                :          * remove the CREATE and replace it with an ALTER.  (Clear out the
                              19326                 :                :          * DROP query too, so that pg_dump --create does not cause errors.)
                              19327                 :                :          */
 1564                         19328                 :            109 :         resetPQExpBuffer(query);
                              19329                 :            109 :         resetPQExpBuffer(delqry);
                              19330                 :            109 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
                              19331         [ -  + ]:            109 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
                              19332                 :            109 :                           fmtQualifiedDumpable(tbinfo));
                              19333   [ +  -  +  +  :            109 :         switch (tginfo->tgenabled)
                                                 - ]
                              19334                 :                :         {
                              19335                 :             38 :             case 'f':
                              19336                 :                :             case 'D':
                              19337                 :             38 :                 appendPQExpBufferStr(query, "DISABLE");
                              19338                 :             38 :                 break;
 1564 alvherre@alvh.no-ip.    19339                 :UBC           0 :             case 't':
                              19340                 :                :             case 'O':
                              19341                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
                              19342                 :              0 :                 break;
 1564 alvherre@alvh.no-ip.    19343                 :CBC          33 :             case 'R':
                              19344                 :             33 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
                              19345                 :             33 :                 break;
                              19346                 :             38 :             case 'A':
                              19347                 :             38 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
                              19348                 :             38 :                 break;
                              19349                 :                :         }
                              19350                 :            109 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
                              19351                 :            109 :                           fmtId(tginfo->dobj.name));
                              19352                 :                :     }
                              19353   [ +  -  -  + ]:            383 :     else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
                              19354                 :                :     {
 2047 alvherre@alvh.no-ip.    19355                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
                              19356         [ #  # ]:              0 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
 2800 tgl@sss.pgh.pa.us       19357                 :              0 :                           fmtQualifiedDumpable(tbinfo));
 6797 JanWieck@Yahoo.com      19358   [ #  #  #  # ]:              0 :         switch (tginfo->tgenabled)
                              19359                 :                :         {
                              19360                 :              0 :             case 'D':
                              19361                 :                :             case 'f':
 4361 heikki.linnakangas@i    19362                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 6797 JanWieck@Yahoo.com      19363                 :              0 :                 break;
                              19364                 :              0 :             case 'A':
 4361 heikki.linnakangas@i    19365                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 6797 JanWieck@Yahoo.com      19366                 :              0 :                 break;
                              19367                 :              0 :             case 'R':
 4361 heikki.linnakangas@i    19368                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 6797 JanWieck@Yahoo.com      19369                 :              0 :                 break;
                              19370                 :              0 :             default:
 4361 heikki.linnakangas@i    19371                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 6797 JanWieck@Yahoo.com      19372                 :              0 :                 break;
                              19373                 :                :         }
                              19374                 :              0 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
 7370 tgl@sss.pgh.pa.us       19375                 :              0 :                           fmtId(tginfo->dobj.name));
                              19376                 :                :     }
                              19377                 :                : 
 2800 tgl@sss.pgh.pa.us       19378                 :CBC         492 :     appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
 5374                         19379                 :            492 :                       fmtId(tginfo->dobj.name));
                              19380                 :                : 
 3532 peter_e@gmx.net         19381                 :            492 :     tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
                              19382                 :                : 
 3491 sfrost@snowman.net      19383         [ +  - ]:            492 :     if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19384                 :            492 :         ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    19385                 :            492 :                      ARCHIVE_OPTS(.tag = tag,
                              19386                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19387                 :                :                                   .owner = tbinfo->rolname,
                              19388                 :                :                                   .description = "TRIGGER",
                              19389                 :                :                                   .section = SECTION_POST_DATA,
                              19390                 :                :                                   .createStmt = query->data,
                              19391                 :                :                                   .dropStmt = delqry->data));
                              19392                 :                : 
 3491 sfrost@snowman.net      19393         [ -  + ]:            492 :     if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       19394                 :UBC           0 :         dumpComment(fout, trigprefix->data, qtabname,
 3491 sfrost@snowman.net      19395                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19396                 :              0 :                     tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
                              19397                 :                : 
 3532 peter_e@gmx.net         19398                 :CBC         492 :     free(tag);
 7996 tgl@sss.pgh.pa.us       19399                 :            492 :     destroyPQExpBuffer(query);
                              19400                 :            492 :     destroyPQExpBuffer(delqry);
 2800                         19401                 :            492 :     destroyPQExpBuffer(trigprefix);
 2056 alvherre@alvh.no-ip.    19402                 :            492 :     destroyPQExpBuffer(trigidentity);
 2800 tgl@sss.pgh.pa.us       19403                 :            492 :     free(qtabname);
                              19404                 :                : }
                              19405                 :                : 
                              19406                 :                : /*
                              19407                 :                :  * dumpEventTrigger
                              19408                 :                :  *    write the declaration of one user-defined event trigger
                              19409                 :                :  */
                              19410                 :                : static void
 1720 peter@eisentraut.org    19411                 :             42 : dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
                              19412                 :                : {
 3575 tgl@sss.pgh.pa.us       19413                 :             42 :     DumpOptions *dopt = fout->dopt;
                              19414                 :                :     PQExpBuffer query;
                              19415                 :                :     PQExpBuffer delqry;
                              19416                 :                :     char       *qevtname;
                              19417                 :                : 
                              19418                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    19419         [ +  + ]:             42 :     if (!dopt->dumpSchema)
 4319 tgl@sss.pgh.pa.us       19420                 :              6 :         return;
                              19421                 :                : 
 4849 rhaas@postgresql.org    19422                 :             36 :     query = createPQExpBuffer();
 3019 tgl@sss.pgh.pa.us       19423                 :             36 :     delqry = createPQExpBuffer();
                              19424                 :                : 
 2800                         19425                 :             36 :     qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
                              19426                 :                : 
 4361 heikki.linnakangas@i    19427                 :             36 :     appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
 2800 tgl@sss.pgh.pa.us       19428                 :             36 :     appendPQExpBufferStr(query, qevtname);
 4361 heikki.linnakangas@i    19429                 :             36 :     appendPQExpBufferStr(query, " ON ");
 4849 rhaas@postgresql.org    19430                 :             36 :     appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
                              19431                 :                : 
                              19432         [ +  + ]:             36 :     if (strcmp("", evtinfo->evttags) != 0)
                              19433                 :                :     {
                              19434                 :              5 :         appendPQExpBufferStr(query, "\n         WHEN TAG IN (");
                              19435                 :              5 :         appendPQExpBufferStr(query, evtinfo->evttags);
 3770 heikki.linnakangas@i    19436                 :              5 :         appendPQExpBufferChar(query, ')');
                              19437                 :                :     }
                              19438                 :                : 
 2454 peter@eisentraut.org    19439                 :             36 :     appendPQExpBufferStr(query, "\n   EXECUTE FUNCTION ");
 4849 rhaas@postgresql.org    19440                 :             36 :     appendPQExpBufferStr(query, evtinfo->evtfname);
 4361 heikki.linnakangas@i    19441                 :             36 :     appendPQExpBufferStr(query, "();\n");
                              19442                 :                : 
 4849 rhaas@postgresql.org    19443         [ -  + ]:             36 :     if (evtinfo->evtenabled != 'O')
                              19444                 :                :     {
 4849 rhaas@postgresql.org    19445                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
                              19446                 :                :                           qevtname);
                              19447   [ #  #  #  # ]:              0 :         switch (evtinfo->evtenabled)
                              19448                 :                :         {
                              19449                 :              0 :             case 'D':
 4361 heikki.linnakangas@i    19450                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 4849 rhaas@postgresql.org    19451                 :              0 :                 break;
                              19452                 :              0 :             case 'A':
 4361 heikki.linnakangas@i    19453                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 4849 rhaas@postgresql.org    19454                 :              0 :                 break;
                              19455                 :              0 :             case 'R':
 4361 heikki.linnakangas@i    19456                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 4849 rhaas@postgresql.org    19457                 :              0 :                 break;
                              19458                 :              0 :             default:
 4361 heikki.linnakangas@i    19459                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 4849 rhaas@postgresql.org    19460                 :              0 :                 break;
                              19461                 :                :         }
 4361 heikki.linnakangas@i    19462                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              19463                 :                :     }
                              19464                 :                : 
 3019 tgl@sss.pgh.pa.us       19465                 :CBC          36 :     appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
                              19466                 :                :                       qevtname);
                              19467                 :                : 
 2638                         19468         [ +  + ]:             36 :     if (dopt->binary_upgrade)
                              19469                 :              2 :         binary_upgrade_extension_member(query, &evtinfo->dobj,
                              19470                 :                :                                         "EVENT TRIGGER", qevtname, NULL);
                              19471                 :                : 
 3491 sfrost@snowman.net      19472         [ +  - ]:             36 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19473                 :             36 :         ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    19474                 :             36 :                      ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
                              19475                 :                :                                   .owner = evtinfo->evtowner,
                              19476                 :                :                                   .description = "EVENT TRIGGER",
                              19477                 :                :                                   .section = SECTION_POST_DATA,
                              19478                 :                :                                   .createStmt = query->data,
                              19479                 :                :                                   .dropStmt = delqry->data));
                              19480                 :                : 
 3491 sfrost@snowman.net      19481         [ -  + ]:             36 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       19482                 :UBC           0 :         dumpComment(fout, "EVENT TRIGGER", qevtname,
 3491 sfrost@snowman.net      19483                 :              0 :                     NULL, evtinfo->evtowner,
                              19484                 :              0 :                     evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
                              19485                 :                : 
   41 fujii@postgresql.org    19486         [ -  + ]:CBC          36 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
   41 fujii@postgresql.org    19487                 :UBC           0 :         dumpSecLabel(fout, "EVENT TRIGGER", qevtname,
                              19488                 :              0 :                      NULL, evtinfo->evtowner,
                              19489                 :              0 :                      evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
                              19490                 :                : 
 4849 rhaas@postgresql.org    19491                 :CBC          36 :     destroyPQExpBuffer(query);
 3019 tgl@sss.pgh.pa.us       19492                 :             36 :     destroyPQExpBuffer(delqry);
 2800                         19493                 :             36 :     free(qevtname);
                              19494                 :                : }
                              19495                 :                : 
                              19496                 :                : /*
                              19497                 :                :  * dumpRule
                              19498                 :                :  *      Dump a rule
                              19499                 :                :  */
                              19500                 :                : static void
 1720 peter@eisentraut.org    19501                 :           1132 : dumpRule(Archive *fout, const RuleInfo *rinfo)
                              19502                 :                : {
 3575 tgl@sss.pgh.pa.us       19503                 :           1132 :     DumpOptions *dopt = fout->dopt;
 7996                         19504                 :           1132 :     TableInfo  *tbinfo = rinfo->ruletable;
                              19505                 :                :     bool        is_view;
                              19506                 :                :     PQExpBuffer query;
                              19507                 :                :     PQExpBuffer cmd;
                              19508                 :                :     PQExpBuffer delcmd;
                              19509                 :                :     PQExpBuffer ruleprefix;
                              19510                 :                :     char       *qtabname;
                              19511                 :                :     PGresult   *res;
                              19512                 :                :     char       *tag;
                              19513                 :                : 
                              19514                 :                :     /* Do nothing if not dumping schema */
  336 nathan@postgresql.or    19515         [ +  + ]:           1132 :     if (!dopt->dumpSchema)
 7996 tgl@sss.pgh.pa.us       19516                 :             60 :         return;
                              19517                 :                : 
                              19518                 :                :     /*
                              19519                 :                :      * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
                              19520                 :                :      * we do not want to dump it as a separate object.
                              19521                 :                :      */
 7622                         19522         [ +  + ]:           1072 :     if (!rinfo->separate)
 7996                         19523                 :            861 :         return;
                              19524                 :                : 
                              19525                 :                :     /*
                              19526                 :                :      * If it's an ON SELECT rule, we want to print it as a view definition,
                              19527                 :                :      * instead of a rule.
                              19528                 :                :      */
 3266                         19529   [ +  +  +  - ]:            211 :     is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
                              19530                 :                : 
 7996                         19531                 :            211 :     query = createPQExpBuffer();
                              19532                 :            211 :     cmd = createPQExpBuffer();
                              19533                 :            211 :     delcmd = createPQExpBuffer();
 2800                         19534                 :            211 :     ruleprefix = createPQExpBuffer();
                              19535                 :                : 
                              19536                 :            211 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              19537                 :                : 
 3266                         19538         [ +  + ]:            211 :     if (is_view)
                              19539                 :                :     {
                              19540                 :                :         PQExpBuffer result;
                              19541                 :                : 
                              19542                 :                :         /*
                              19543                 :                :          * We need OR REPLACE here because we'll be replacing a dummy view.
                              19544                 :                :          * Otherwise this should look largely like the regular view dump code.
                              19545                 :                :          */
                              19546                 :             10 :         appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
 2800                         19547                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 3266                         19548         [ -  + ]:             10 :         if (nonemptyReloptions(tbinfo->reloptions))
                              19549                 :                :         {
 3266 tgl@sss.pgh.pa.us       19550                 :UBC           0 :             appendPQExpBufferStr(cmd, " WITH (");
                              19551                 :              0 :             appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
                              19552                 :              0 :             appendPQExpBufferChar(cmd, ')');
                              19553                 :                :         }
 3266 tgl@sss.pgh.pa.us       19554                 :CBC          10 :         result = createViewAsClause(fout, tbinfo);
                              19555                 :             10 :         appendPQExpBuffer(cmd, " AS\n%s", result->data);
                              19556                 :             10 :         destroyPQExpBuffer(result);
                              19557         [ -  + ]:             10 :         if (tbinfo->checkoption != NULL)
 3266 tgl@sss.pgh.pa.us       19558                 :UBC           0 :             appendPQExpBuffer(cmd, "\n  WITH %s CHECK OPTION",
                              19559                 :                :                               tbinfo->checkoption);
 3266 tgl@sss.pgh.pa.us       19560                 :CBC          10 :         appendPQExpBufferStr(cmd, ";\n");
                              19561                 :                :     }
                              19562                 :                :     else
                              19563                 :                :     {
                              19564                 :                :         /* In the rule case, just print pg_get_ruledef's result verbatim */
                              19565                 :            201 :         appendPQExpBuffer(query,
                              19566                 :                :                           "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
                              19567                 :            201 :                           rinfo->dobj.catId.oid);
                              19568                 :                : 
                              19569                 :            201 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19570                 :                : 
                              19571         [ -  + ]:            201 :         if (PQntuples(res) != 1)
 1298 tgl@sss.pgh.pa.us       19572                 :UBC           0 :             pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
                              19573                 :                :                      rinfo->dobj.name, tbinfo->dobj.name);
                              19574                 :                : 
 3266 tgl@sss.pgh.pa.us       19575                 :CBC         201 :         printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
                              19576                 :                : 
                              19577                 :            201 :         PQclear(res);
                              19578                 :                :     }
                              19579                 :                : 
                              19580                 :                :     /*
                              19581                 :                :      * Add the command to alter the rules replication firing semantics if it
                              19582                 :                :      * differs from the default.
                              19583                 :                :      */
 6797 JanWieck@Yahoo.com      19584         [ +  + ]:            211 :     if (rinfo->ev_enabled != 'O')
                              19585                 :                :     {
 2800 tgl@sss.pgh.pa.us       19586                 :             15 :         appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
 6797 JanWieck@Yahoo.com      19587   [ -  -  +  - ]:             15 :         switch (rinfo->ev_enabled)
                              19588                 :                :         {
 6797 JanWieck@Yahoo.com      19589                 :UBC           0 :             case 'A':
                              19590                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
 6556 bruce@momjian.us        19591                 :              0 :                                   fmtId(rinfo->dobj.name));
 6797 JanWieck@Yahoo.com      19592                 :              0 :                 break;
                              19593                 :              0 :             case 'R':
                              19594                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
 6556 bruce@momjian.us        19595                 :              0 :                                   fmtId(rinfo->dobj.name));
 6797 JanWieck@Yahoo.com      19596                 :              0 :                 break;
 6797 JanWieck@Yahoo.com      19597                 :CBC          15 :             case 'D':
                              19598                 :             15 :                 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
 6556 bruce@momjian.us        19599                 :             15 :                                   fmtId(rinfo->dobj.name));
 6797 JanWieck@Yahoo.com      19600                 :             15 :                 break;
                              19601                 :                :         }
                              19602                 :                :     }
                              19603                 :                : 
 3266 tgl@sss.pgh.pa.us       19604         [ +  + ]:            211 :     if (is_view)
                              19605                 :                :     {
                              19606                 :                :         /*
                              19607                 :                :          * We can't DROP a view's ON SELECT rule.  Instead, use CREATE OR
                              19608                 :                :          * REPLACE VIEW to replace the rule with something with minimal
                              19609                 :                :          * dependencies.
                              19610                 :                :          */
                              19611                 :                :         PQExpBuffer result;
                              19612                 :                : 
 2800                         19613                 :             10 :         appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
                              19614                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 3266                         19615                 :             10 :         result = createDummyViewAsClause(fout, tbinfo);
                              19616                 :             10 :         appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
                              19617                 :             10 :         destroyPQExpBuffer(result);
                              19618                 :                :     }
                              19619                 :                :     else
                              19620                 :                :     {
                              19621                 :            201 :         appendPQExpBuffer(delcmd, "DROP RULE %s ",
                              19622                 :            201 :                           fmtId(rinfo->dobj.name));
 2800                         19623                 :            201 :         appendPQExpBuffer(delcmd, "ON %s;\n",
                              19624                 :            201 :                           fmtQualifiedDumpable(tbinfo));
                              19625                 :                :     }
                              19626                 :                : 
                              19627                 :            211 :     appendPQExpBuffer(ruleprefix, "RULE %s ON",
 5374                         19628                 :            211 :                       fmtId(rinfo->dobj.name));
                              19629                 :                : 
 3532 peter_e@gmx.net         19630                 :            211 :     tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
                              19631                 :                : 
 3491 sfrost@snowman.net      19632         [ +  - ]:            211 :     if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19633                 :            211 :         ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
 2460 alvherre@alvh.no-ip.    19634                 :            211 :                      ARCHIVE_OPTS(.tag = tag,
                              19635                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19636                 :                :                                   .owner = tbinfo->rolname,
                              19637                 :                :                                   .description = "RULE",
                              19638                 :                :                                   .section = SECTION_POST_DATA,
                              19639                 :                :                                   .createStmt = cmd->data,
                              19640                 :                :                                   .dropStmt = delcmd->data));
                              19641                 :                : 
                              19642                 :                :     /* Dump rule comments */
 3491 sfrost@snowman.net      19643         [ -  + ]:            211 :     if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2800 tgl@sss.pgh.pa.us       19644                 :UBC           0 :         dumpComment(fout, ruleprefix->data, qtabname,
 3491 sfrost@snowman.net      19645                 :              0 :                     tbinfo->dobj.namespace->dobj.name,
                              19646                 :                :                     tbinfo->rolname,
                              19647                 :              0 :                     rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
                              19648                 :                : 
 3532 peter_e@gmx.net         19649                 :CBC         211 :     free(tag);
 8571 tgl@sss.pgh.pa.us       19650                 :            211 :     destroyPQExpBuffer(query);
 7996                         19651                 :            211 :     destroyPQExpBuffer(cmd);
                              19652                 :            211 :     destroyPQExpBuffer(delcmd);
 2800                         19653                 :            211 :     destroyPQExpBuffer(ruleprefix);
                              19654                 :            211 :     free(qtabname);
                              19655                 :                : }
                              19656                 :                : 
                              19657                 :                : /*
                              19658                 :                :  * getExtensionMembership --- obtain extension membership data
                              19659                 :                :  *
                              19660                 :                :  * We need to identify objects that are extension members as soon as they're
                              19661                 :                :  * loaded, so that we can correctly determine whether they need to be dumped.
                              19662                 :                :  * Generally speaking, extension member objects will get marked as *not* to
                              19663                 :                :  * be dumped, as they will be recreated by the single CREATE EXTENSION
                              19664                 :                :  * command.  However, in binary upgrade mode we still need to dump the members
                              19665                 :                :  * individually.
                              19666                 :                :  */
                              19667                 :                : void
 3575                         19668                 :            190 : getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                              19669                 :                :                        int numExtensions)
                              19670                 :                : {
                              19671                 :                :     PQExpBuffer query;
                              19672                 :                :     PGresult   *res;
                              19673                 :                :     int         ntups,
                              19674                 :                :                 i;
                              19675                 :                :     int         i_classid,
                              19676                 :                :                 i_objid,
                              19677                 :                :                 i_refobjid;
                              19678                 :                :     ExtensionInfo *ext;
                              19679                 :                : 
                              19680                 :                :     /* Nothing to do if no extensions */
 5374                         19681         [ -  + ]:            190 :     if (numExtensions == 0)
 5374 tgl@sss.pgh.pa.us       19682                 :UBC           0 :         return;
                              19683                 :                : 
 5374 tgl@sss.pgh.pa.us       19684                 :CBC         190 :     query = createPQExpBuffer();
                              19685                 :                : 
                              19686                 :                :     /* refclassid constraint is redundant but may speed the search */
 4361 heikki.linnakangas@i    19687                 :            190 :     appendPQExpBufferStr(query, "SELECT "
                              19688                 :                :                          "classid, objid, refobjid "
                              19689                 :                :                          "FROM pg_depend "
                              19690                 :                :                          "WHERE refclassid = 'pg_extension'::regclass "
                              19691                 :                :                          "AND deptype = 'e' "
                              19692                 :                :                          "ORDER BY 3");
                              19693                 :                : 
 5011 rhaas@postgresql.org    19694                 :            190 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19695                 :                : 
 5374 tgl@sss.pgh.pa.us       19696                 :            190 :     ntups = PQntuples(res);
                              19697                 :                : 
                              19698                 :            190 :     i_classid = PQfnumber(res, "classid");
                              19699                 :            190 :     i_objid = PQfnumber(res, "objid");
                              19700                 :            190 :     i_refobjid = PQfnumber(res, "refobjid");
                              19701                 :                : 
                              19702                 :                :     /*
                              19703                 :                :      * Since we ordered the SELECT by referenced ID, we can expect that
                              19704                 :                :      * multiple entries for the same extension will appear together; this
                              19705                 :                :      * saves on searches.
                              19706                 :                :      */
 3575                         19707                 :            190 :     ext = NULL;
                              19708                 :                : 
 5374                         19709         [ +  + ]:           1555 :     for (i = 0; i < ntups; i++)
                              19710                 :                :     {
                              19711                 :                :         CatalogId   objId;
                              19712                 :                :         Oid         extId;
                              19713                 :                : 
                              19714                 :           1365 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              19715                 :           1365 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
 3575                         19716                 :           1365 :         extId = atooid(PQgetvalue(res, i, i_refobjid));
                              19717                 :                : 
                              19718         [ +  + ]:           1365 :         if (ext == NULL ||
                              19719         [ +  + ]:           1175 :             ext->dobj.catId.oid != extId)
                              19720                 :            220 :             ext = findExtensionByOid(extId);
                              19721                 :                : 
                              19722         [ -  + ]:           1365 :         if (ext == NULL)
                              19723                 :                :         {
                              19724                 :                :             /* shouldn't happen */
 2401 peter@eisentraut.org    19725                 :UBC           0 :             pg_log_warning("could not find referenced extension %u", extId);
 5374 tgl@sss.pgh.pa.us       19726                 :              0 :             continue;
                              19727                 :                :         }
                              19728                 :                : 
 1466 tgl@sss.pgh.pa.us       19729                 :CBC        1365 :         recordExtensionMembership(objId, ext);
                              19730                 :                :     }
                              19731                 :                : 
 3575                         19732                 :            190 :     PQclear(res);
                              19733                 :                : 
                              19734                 :            190 :     destroyPQExpBuffer(query);
                              19735                 :                : }
                              19736                 :                : 
                              19737                 :                : /*
                              19738                 :                :  * processExtensionTables --- deal with extension configuration tables
                              19739                 :                :  *
                              19740                 :                :  * There are two parts to this process:
                              19741                 :                :  *
                              19742                 :                :  * 1. Identify and create dump records for extension configuration tables.
                              19743                 :                :  *
                              19744                 :                :  *    Extensions can mark tables as "configuration", which means that the user
                              19745                 :                :  *    is able and expected to modify those tables after the extension has been
                              19746                 :                :  *    loaded.  For these tables, we dump out only the data- the structure is
                              19747                 :                :  *    expected to be handled at CREATE EXTENSION time, including any indexes or
                              19748                 :                :  *    foreign keys, which brings us to-
                              19749                 :                :  *
                              19750                 :                :  * 2. Record FK dependencies between configuration tables.
                              19751                 :                :  *
                              19752                 :                :  *    Due to the FKs being created at CREATE EXTENSION time and therefore before
                              19753                 :                :  *    the data is loaded, we have to work out what the best order for reloading
                              19754                 :                :  *    the data is, to avoid FK violations when the tables are restored.  This is
                              19755                 :                :  *    not perfect- we can't handle circular dependencies and if any exist they
                              19756                 :                :  *    will cause an invalid dump to be produced (though at least all of the data
                              19757                 :                :  *    is included for a user to manually restore).  This is currently documented
                              19758                 :                :  *    but perhaps we can provide a better solution in the future.
                              19759                 :                :  */
                              19760                 :                : void
                              19761                 :            189 : processExtensionTables(Archive *fout, ExtensionInfo extinfo[],
                              19762                 :                :                        int numExtensions)
                              19763                 :                : {
                              19764                 :            189 :     DumpOptions *dopt = fout->dopt;
                              19765                 :                :     PQExpBuffer query;
                              19766                 :                :     PGresult   *res;
                              19767                 :                :     int         ntups,
                              19768                 :                :                 i;
                              19769                 :                :     int         i_conrelid,
                              19770                 :                :                 i_confrelid;
                              19771                 :                : 
                              19772                 :                :     /* Nothing to do if no extensions */
                              19773         [ -  + ]:            189 :     if (numExtensions == 0)
 3575 tgl@sss.pgh.pa.us       19774                 :UBC           0 :         return;
                              19775                 :                : 
                              19776                 :                :     /*
                              19777                 :                :      * Identify extension configuration tables and create TableDataInfo
                              19778                 :                :      * objects for them, ensuring their data will be dumped even though the
                              19779                 :                :      * tables themselves won't be.
                              19780                 :                :      *
                              19781                 :                :      * Note that we create TableDataInfo objects even in schema-only mode, ie,
                              19782                 :                :      * user data in a configuration table is treated like schema data. This
                              19783                 :                :      * seems appropriate since system data in a config table would get
                              19784                 :                :      * reloaded by CREATE EXTENSION.  If the extension is not listed in the
                              19785                 :                :      * list of extensions to be included, none of its data is dumped.
                              19786                 :                :      */
 5374 tgl@sss.pgh.pa.us       19787         [ +  + ]:CBC         408 :     for (i = 0; i < numExtensions; i++)
                              19788                 :                :     {
 5008                         19789                 :            219 :         ExtensionInfo *curext = &(extinfo[i]);
                              19790                 :            219 :         char       *extconfig = curext->extconfig;
                              19791                 :            219 :         char       *extcondition = curext->extcondition;
 5314 bruce@momjian.us        19792                 :            219 :         char      **extconfigarray = NULL;
                              19793                 :            219 :         char      **extconditionarray = NULL;
 1803 michael@paquier.xyz     19794                 :            219 :         int         nconfigitems = 0;
                              19795                 :            219 :         int         nconditionitems = 0;
                              19796                 :                : 
                              19797                 :                :         /*
                              19798                 :                :          * Check if this extension is listed as to include in the dump.  If
                              19799                 :                :          * not, any table data associated with it is discarded.
                              19800                 :                :          */
 1656                         19801         [ +  + ]:            219 :         if (extension_include_oids.head != NULL &&
                              19802         [ +  + ]:              8 :             !simple_oid_list_member(&extension_include_oids,
                              19803                 :                :                                     curext->dobj.catId.oid))
                              19804                 :              6 :             continue;
                              19805                 :                : 
                              19806                 :                :         /*
                              19807                 :                :          * Check if this extension is listed as to exclude in the dump.  If
                              19808                 :                :          * yes, any table data associated with it is discarded.
                              19809                 :                :          */
  586 dean.a.rasheed@gmail    19810   [ +  +  +  + ]:            219 :         if (extension_exclude_oids.head != NULL &&
                              19811                 :              4 :             simple_oid_list_member(&extension_exclude_oids,
                              19812                 :                :                                    curext->dobj.catId.oid))
                              19813                 :              2 :             continue;
                              19814                 :                : 
 1803 michael@paquier.xyz     19815   [ +  +  -  + ]:            213 :         if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
                              19816                 :                :         {
                              19817                 :                :             int         j;
                              19818                 :                : 
                              19819         [ -  + ]:             20 :             if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
 1298 tgl@sss.pgh.pa.us       19820                 :UBC           0 :                 pg_fatal("could not parse %s array", "extconfig");
 1803 michael@paquier.xyz     19821         [ -  + ]:CBC          20 :             if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
 1298 tgl@sss.pgh.pa.us       19822                 :UBC           0 :                 pg_fatal("could not parse %s array", "extcondition");
 1803 michael@paquier.xyz     19823         [ -  + ]:CBC          20 :             if (nconfigitems != nconditionitems)
 1298 tgl@sss.pgh.pa.us       19824                 :UBC           0 :                 pg_fatal("mismatched number of configurations and conditions for extension");
                              19825                 :                : 
 5374 tgl@sss.pgh.pa.us       19826         [ +  + ]:CBC          60 :             for (j = 0; j < nconfigitems; j++)
                              19827                 :                :             {
                              19828                 :                :                 TableInfo  *configtbl;
 4567 mail@joeconway.com      19829                 :             40 :                 Oid         configtbloid = atooid(extconfigarray[j]);
 3491 sfrost@snowman.net      19830                 :             40 :                 bool        dumpobj =
  892 tgl@sss.pgh.pa.us       19831                 :             40 :                     curext->dobj.dump & DUMP_COMPONENT_DEFINITION;
                              19832                 :                : 
 4567 mail@joeconway.com      19833                 :             40 :                 configtbl = findTableByOid(configtbloid);
 5010 tgl@sss.pgh.pa.us       19834         [ -  + ]:             40 :                 if (configtbl == NULL)
 5010 tgl@sss.pgh.pa.us       19835                 :UBC           0 :                     continue;
                              19836                 :                : 
                              19837                 :                :                 /*
                              19838                 :                :                  * Tables of not-to-be-dumped extensions shouldn't be dumped
                              19839                 :                :                  * unless the table or its schema is explicitly included
                              19840                 :                :                  */
 3491 sfrost@snowman.net      19841         [ +  + ]:CBC          40 :                 if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
                              19842                 :                :                 {
                              19843                 :                :                     /* check table explicitly requested */
 4567 mail@joeconway.com      19844   [ -  +  -  - ]:              2 :                     if (table_include_oids.head != NULL &&
 4567 mail@joeconway.com      19845                 :UBC           0 :                         simple_oid_list_member(&table_include_oids,
                              19846                 :                :                                                configtbloid))
                              19847                 :              0 :                         dumpobj = true;
                              19848                 :                : 
                              19849                 :                :                     /* check table's schema explicitly requested */
 3491 sfrost@snowman.net      19850         [ +  - ]:CBC           2 :                     if (configtbl->dobj.namespace->dobj.dump &
                              19851                 :                :                         DUMP_COMPONENT_DATA)
 4567 mail@joeconway.com      19852                 :              2 :                         dumpobj = true;
                              19853                 :                :                 }
                              19854                 :                : 
                              19855                 :                :                 /* check table excluded by an exclusion switch */
                              19856   [ +  +  +  + ]:             44 :                 if (table_exclude_oids.head != NULL &&
                              19857                 :              4 :                     simple_oid_list_member(&table_exclude_oids,
                              19858                 :                :                                            configtbloid))
                              19859                 :              1 :                     dumpobj = false;
                              19860                 :                : 
                              19861                 :                :                 /* check schema excluded by an exclusion switch */
                              19862         [ -  + ]:             40 :                 if (simple_oid_list_member(&schema_exclude_oids,
 3050 tgl@sss.pgh.pa.us       19863                 :             40 :                                            configtbl->dobj.namespace->dobj.catId.oid))
 4567 mail@joeconway.com      19864                 :UBC           0 :                     dumpobj = false;
                              19865                 :                : 
 4567 mail@joeconway.com      19866         [ +  + ]:CBC          40 :                 if (dumpobj)
                              19867                 :                :                 {
 2533 andres@anarazel.de      19868                 :             39 :                     makeTableDataInfo(dopt, configtbl);
 4567 mail@joeconway.com      19869         [ +  - ]:             39 :                     if (configtbl->dataObj != NULL)
                              19870                 :                :                     {
                              19871         [ -  + ]:             39 :                         if (strlen(extconditionarray[j]) > 0)
 4567 mail@joeconway.com      19872                 :UBC           0 :                             configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
                              19873                 :                :                     }
                              19874                 :                :                 }
                              19875                 :                :             }
                              19876                 :                :         }
 5374 tgl@sss.pgh.pa.us       19877         [ +  + ]:CBC         213 :         if (extconfigarray)
                              19878                 :             20 :             free(extconfigarray);
                              19879         [ +  + ]:            213 :         if (extconditionarray)
                              19880                 :             20 :             free(extconditionarray);
                              19881                 :                :     }
                              19882                 :                : 
                              19883                 :                :     /*
                              19884                 :                :      * Now that all the TableDataInfo objects have been created for all the
                              19885                 :                :      * extensions, check their FK dependencies and register them to try and
                              19886                 :                :      * dump the data out in an order that they can be restored in.
                              19887                 :                :      *
                              19888                 :                :      * Note that this is not a problem for user tables as their FKs are
                              19889                 :                :      * recreated after the data has been loaded.
                              19890                 :                :      */
                              19891                 :                : 
 3575                         19892                 :            189 :     query = createPQExpBuffer();
                              19893                 :                : 
 3892 sfrost@snowman.net      19894                 :            189 :     printfPQExpBuffer(query,
                              19895                 :                :                       "SELECT conrelid, confrelid "
                              19896                 :                :                       "FROM pg_constraint "
                              19897                 :                :                       "JOIN pg_depend ON (objid = confrelid) "
                              19898                 :                :                       "WHERE contype = 'f' "
                              19899                 :                :                       "AND refclassid = 'pg_extension'::regclass "
                              19900                 :                :                       "AND classid = 'pg_class'::regclass;");
                              19901                 :                : 
                              19902                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19903                 :            189 :     ntups = PQntuples(res);
                              19904                 :                : 
                              19905                 :            189 :     i_conrelid = PQfnumber(res, "conrelid");
                              19906                 :            189 :     i_confrelid = PQfnumber(res, "confrelid");
                              19907                 :                : 
                              19908                 :                :     /* Now get the dependencies and register them */
                              19909         [ -  + ]:            189 :     for (i = 0; i < ntups; i++)
                              19910                 :                :     {
                              19911                 :                :         Oid         conrelid,
                              19912                 :                :                     confrelid;
                              19913                 :                :         TableInfo  *reftable,
                              19914                 :                :                    *contable;
                              19915                 :                : 
 3892 sfrost@snowman.net      19916                 :UBC           0 :         conrelid = atooid(PQgetvalue(res, i, i_conrelid));
                              19917                 :              0 :         confrelid = atooid(PQgetvalue(res, i, i_confrelid));
                              19918                 :              0 :         contable = findTableByOid(conrelid);
                              19919                 :              0 :         reftable = findTableByOid(confrelid);
                              19920                 :                : 
                              19921         [ #  # ]:              0 :         if (reftable == NULL ||
                              19922   [ #  #  #  # ]:              0 :             reftable->dataObj == NULL ||
                              19923                 :              0 :             contable == NULL ||
                              19924         [ #  # ]:              0 :             contable->dataObj == NULL)
                              19925                 :              0 :             continue;
                              19926                 :                : 
                              19927                 :                :         /*
                              19928                 :                :          * Make referencing TABLE_DATA object depend on the referenced table's
                              19929                 :                :          * TABLE_DATA object.
                              19930                 :                :          */
                              19931                 :              0 :         addObjectDependency(&contable->dataObj->dobj,
                              19932                 :              0 :                             reftable->dataObj->dobj.dumpId);
                              19933                 :                :     }
 3760 tgl@sss.pgh.pa.us       19934                 :CBC         189 :     PQclear(res);
 5374                         19935                 :            189 :     destroyPQExpBuffer(query);
                              19936                 :                : }
                              19937                 :                : 
                              19938                 :                : /*
                              19939                 :                :  * getDependencies --- obtain available dependency data
                              19940                 :                :  */
                              19941                 :                : static void
 5012 rhaas@postgresql.org    19942                 :            189 : getDependencies(Archive *fout)
                              19943                 :                : {
                              19944                 :                :     PQExpBuffer query;
                              19945                 :                :     PGresult   *res;
                              19946                 :                :     int         ntups,
                              19947                 :                :                 i;
                              19948                 :                :     int         i_classid,
                              19949                 :                :                 i_objid,
                              19950                 :                :                 i_refclassid,
                              19951                 :                :                 i_refobjid,
                              19952                 :                :                 i_deptype;
                              19953                 :                :     DumpableObject *dobj,
                              19954                 :                :                *refdobj;
                              19955                 :                : 
 2401 peter@eisentraut.org    19956                 :            189 :     pg_log_info("reading dependency data");
                              19957                 :                : 
 7996 tgl@sss.pgh.pa.us       19958                 :            189 :     query = createPQExpBuffer();
                              19959                 :                : 
                              19960                 :                :     /*
                              19961                 :                :      * Messy query to collect the dependency data we need.  Note that we
                              19962                 :                :      * ignore the sub-object column, so that dependencies of or on a column
                              19963                 :                :      * look the same as dependencies of or on a whole table.
                              19964                 :                :      *
                              19965                 :                :      * PIN dependencies aren't interesting, and EXTENSION dependencies were
                              19966                 :                :      * already processed by getExtensionMembership.
                              19967                 :                :      */
 4361 heikki.linnakangas@i    19968                 :            189 :     appendPQExpBufferStr(query, "SELECT "
                              19969                 :                :                          "classid, objid, refclassid, refobjid, deptype "
                              19970                 :                :                          "FROM pg_depend "
                              19971                 :                :                          "WHERE deptype != 'p' AND deptype != 'e'\n");
                              19972                 :                : 
                              19973                 :                :     /*
                              19974                 :                :      * Since we don't treat pg_amop entries as separate DumpableObjects, we
                              19975                 :                :      * have to translate their dependencies into dependencies of their parent
                              19976                 :                :      * opfamily.  Ignore internal dependencies though, as those will point to
                              19977                 :                :      * their parent opclass, which we needn't consider here (and if we did,
                              19978                 :                :      * it'd just result in circular dependencies).  Also, "loose" opfamily
                              19979                 :                :      * entries will have dependencies on their parent opfamily, which we
                              19980                 :                :      * should drop since they'd likewise become useless self-dependencies.
                              19981                 :                :      * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
                              19982                 :                :      */
 1413 tgl@sss.pgh.pa.us       19983                 :            189 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              19984                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
                              19985                 :                :                          "FROM pg_depend d, pg_amop o "
                              19986                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              19987                 :                :                          "classid = 'pg_amop'::regclass AND objid = o.oid "
                              19988                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
                              19989                 :                : 
                              19990                 :                :     /* Likewise for pg_amproc entries */
                              19991                 :            189 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              19992                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
                              19993                 :                :                          "FROM pg_depend d, pg_amproc p "
                              19994                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              19995                 :                :                          "classid = 'pg_amproc'::regclass AND objid = p.oid "
                              19996                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
                              19997                 :                : 
                              19998                 :                :     /* Sort the output for efficiency below */
 2280                         19999                 :            189 :     appendPQExpBufferStr(query, "ORDER BY 1,2");
                              20000                 :                : 
 5011 rhaas@postgresql.org    20001                 :            189 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              20002                 :                : 
 7996 tgl@sss.pgh.pa.us       20003                 :            189 :     ntups = PQntuples(res);
                              20004                 :                : 
                              20005                 :            189 :     i_classid = PQfnumber(res, "classid");
                              20006                 :            189 :     i_objid = PQfnumber(res, "objid");
                              20007                 :            189 :     i_refclassid = PQfnumber(res, "refclassid");
                              20008                 :            189 :     i_refobjid = PQfnumber(res, "refobjid");
                              20009                 :            189 :     i_deptype = PQfnumber(res, "deptype");
                              20010                 :                : 
                              20011                 :                :     /*
                              20012                 :                :      * Since we ordered the SELECT by referencing ID, we can expect that
                              20013                 :                :      * multiple entries for the same object will appear together; this saves
                              20014                 :                :      * on searches.
                              20015                 :                :      */
                              20016                 :            189 :     dobj = NULL;
                              20017                 :                : 
                              20018         [ +  + ]:         407162 :     for (i = 0; i < ntups; i++)
                              20019                 :                :     {
                              20020                 :                :         CatalogId   objId;
                              20021                 :                :         CatalogId   refobjId;
                              20022                 :                :         char        deptype;
                              20023                 :                : 
                              20024                 :         406973 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              20025                 :         406973 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                              20026                 :         406973 :         refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
                              20027                 :         406973 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                              20028                 :         406973 :         deptype = *(PQgetvalue(res, i, i_deptype));
                              20029                 :                : 
                              20030         [ +  + ]:         406973 :         if (dobj == NULL ||
                              20031         [ +  + ]:         382348 :             dobj->catId.tableoid != objId.tableoid ||
                              20032         [ +  + ]:         380226 :             dobj->catId.oid != objId.oid)
                              20033                 :         177310 :             dobj = findObjectByCatalogId(objId);
                              20034                 :                : 
                              20035                 :                :         /*
                              20036                 :                :          * Failure to find objects mentioned in pg_depend is not unexpected,
                              20037                 :                :          * since for example we don't collect info about TOAST tables.
                              20038                 :                :          */
                              20039         [ +  + ]:         406973 :         if (dobj == NULL)
                              20040                 :                :         {
                              20041                 :                : #ifdef NOT_USED
                              20042                 :                :             pg_log_warning("no referencing object %u %u",
                              20043                 :                :                            objId.tableoid, objId.oid);
                              20044                 :                : #endif
                              20045                 :          25305 :             continue;
                              20046                 :                :         }
                              20047                 :                : 
                              20048                 :         382537 :         refdobj = findObjectByCatalogId(refobjId);
                              20049                 :                : 
                              20050         [ +  + ]:         382537 :         if (refdobj == NULL)
                              20051                 :                :         {
                              20052                 :                : #ifdef NOT_USED
                              20053                 :                :             pg_log_warning("no referenced object %u %u",
                              20054                 :                :                            refobjId.tableoid, refobjId.oid);
                              20055                 :                : #endif
                              20056                 :            869 :             continue;
                              20057                 :                :         }
                              20058                 :                : 
                              20059                 :                :         /*
                              20060                 :                :          * For 'x' dependencies, mark the object for later; we still add the
                              20061                 :                :          * normal dependency, for possible ordering purposes.  Currently
                              20062                 :                :          * pg_dump_sort.c knows to put extensions ahead of all object types
                              20063                 :                :          * that could possibly depend on them, but this is safer.
                              20064                 :                :          */
 2056 alvherre@alvh.no-ip.    20065         [ +  + ]:         381668 :         if (deptype == 'x')
                              20066                 :             44 :             dobj->depends_on_ext = true;
                              20067                 :                : 
                              20068                 :                :         /*
                              20069                 :                :          * Ordinarily, table rowtypes have implicit dependencies on their
                              20070                 :                :          * tables.  However, for a composite type the implicit dependency goes
                              20071                 :                :          * the other way in pg_depend; which is the right thing for DROP but
                              20072                 :                :          * it doesn't produce the dependency ordering we need. So in that one
                              20073                 :                :          * case, we reverse the direction of the dependency.
                              20074                 :                :          */
 7594 tgl@sss.pgh.pa.us       20075         [ +  + ]:         381668 :         if (deptype == 'i' &&
                              20076         [ +  + ]:         107129 :             dobj->objType == DO_TABLE &&
                              20077         [ +  + ]:           1244 :             refdobj->objType == DO_TYPE)
                              20078                 :            182 :             addObjectDependency(refdobj, dobj->dumpId);
                              20079                 :                :         else
                              20080                 :                :             /* normal case */
                              20081                 :         381486 :             addObjectDependency(dobj, refdobj->dumpId);
                              20082                 :                :     }
                              20083                 :                : 
 7996                         20084                 :            189 :     PQclear(res);
                              20085                 :                : 
 8851                         20086                 :            189 :     destroyPQExpBuffer(query);
 9883 bruce@momjian.us        20087                 :            189 : }
                              20088                 :                : 
                              20089                 :                : 
                              20090                 :                : /*
                              20091                 :                :  * createBoundaryObjects - create dummy DumpableObjects to represent
                              20092                 :                :  * dump section boundaries.
                              20093                 :                :  */
                              20094                 :                : static DumpableObject *
 4872 tgl@sss.pgh.pa.us       20095                 :            189 : createBoundaryObjects(void)
                              20096                 :                : {
                              20097                 :                :     DumpableObject *dobjs;
                              20098                 :                : 
                              20099                 :            189 :     dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
                              20100                 :                : 
                              20101                 :            189 :     dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
                              20102                 :            189 :     dobjs[0].catId = nilCatalogId;
                              20103                 :            189 :     AssignDumpId(dobjs + 0);
                              20104                 :            189 :     dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
                              20105                 :                : 
                              20106                 :            189 :     dobjs[1].objType = DO_POST_DATA_BOUNDARY;
                              20107                 :            189 :     dobjs[1].catId = nilCatalogId;
                              20108                 :            189 :     AssignDumpId(dobjs + 1);
                              20109                 :            189 :     dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
                              20110                 :                : 
                              20111                 :            189 :     return dobjs;
                              20112                 :                : }
                              20113                 :                : 
                              20114                 :                : /*
                              20115                 :                :  * addBoundaryDependencies - add dependencies as needed to enforce the dump
                              20116                 :                :  * section boundaries.
                              20117                 :                :  */
                              20118                 :                : static void
                              20119                 :            189 : addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
                              20120                 :                :                         DumpableObject *boundaryObjs)
                              20121                 :                : {
                              20122                 :            189 :     DumpableObject *preDataBound = boundaryObjs + 0;
                              20123                 :            189 :     DumpableObject *postDataBound = boundaryObjs + 1;
                              20124                 :                :     int         i;
                              20125                 :                : 
                              20126         [ +  + ]:         832807 :     for (i = 0; i < numObjs; i++)
                              20127                 :                :     {
                              20128                 :         832618 :         DumpableObject *dobj = dobjs[i];
                              20129                 :                : 
                              20130                 :                :         /*
                              20131                 :                :          * The classification of object types here must match the SECTION_xxx
                              20132                 :                :          * values assigned during subsequent ArchiveEntry calls!
                              20133                 :                :          */
                              20134   [ +  +  +  +  :         832618 :         switch (dobj->objType)
                                        +  +  +  +  
                                                 - ]
                              20135                 :                :         {
                              20136                 :         786609 :             case DO_NAMESPACE:
                              20137                 :                :             case DO_EXTENSION:
                              20138                 :                :             case DO_TYPE:
                              20139                 :                :             case DO_SHELL_TYPE:
                              20140                 :                :             case DO_FUNC:
                              20141                 :                :             case DO_AGG:
                              20142                 :                :             case DO_OPERATOR:
                              20143                 :                :             case DO_ACCESS_METHOD:
                              20144                 :                :             case DO_OPCLASS:
                              20145                 :                :             case DO_OPFAMILY:
                              20146                 :                :             case DO_COLLATION:
                              20147                 :                :             case DO_CONVERSION:
                              20148                 :                :             case DO_TABLE:
                              20149                 :                :             case DO_TABLE_ATTACH:
                              20150                 :                :             case DO_ATTRDEF:
                              20151                 :                :             case DO_PROCLANG:
                              20152                 :                :             case DO_CAST:
                              20153                 :                :             case DO_DUMMY_TYPE:
                              20154                 :                :             case DO_TSPARSER:
                              20155                 :                :             case DO_TSDICT:
                              20156                 :                :             case DO_TSTEMPLATE:
                              20157                 :                :             case DO_TSCONFIG:
                              20158                 :                :             case DO_FDW:
                              20159                 :                :             case DO_FOREIGN_SERVER:
                              20160                 :                :             case DO_TRANSFORM:
                              20161                 :                :                 /* Pre-data objects: must come before the pre-data boundary */
                              20162                 :         786609 :                 addObjectDependency(preDataBound, dobj->dumpId);
                              20163                 :         786609 :                 break;
                              20164                 :           4803 :             case DO_TABLE_DATA:
                              20165                 :                :             case DO_SEQUENCE_SET:
                              20166                 :                :             case DO_LARGE_OBJECT:
                              20167                 :                :             case DO_LARGE_OBJECT_DATA:
                              20168                 :                :                 /* Data objects: must come between the boundaries */
                              20169                 :           4803 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              20170                 :           4803 :                 addObjectDependency(postDataBound, dobj->dumpId);
                              20171                 :           4803 :                 break;
                              20172                 :           5709 :             case DO_INDEX:
                              20173                 :                :             case DO_INDEX_ATTACH:
                              20174                 :                :             case DO_STATSEXT:
                              20175                 :                :             case DO_REFRESH_MATVIEW:
                              20176                 :                :             case DO_TRIGGER:
                              20177                 :                :             case DO_EVENT_TRIGGER:
                              20178                 :                :             case DO_DEFAULT_ACL:
                              20179                 :                :             case DO_POLICY:
                              20180                 :                :             case DO_PUBLICATION:
                              20181                 :                :             case DO_PUBLICATION_REL:
                              20182                 :                :             case DO_PUBLICATION_TABLE_IN_SCHEMA:
                              20183                 :                :             case DO_SUBSCRIPTION:
                              20184                 :                :             case DO_SUBSCRIPTION_REL:
                              20185                 :                :                 /* Post-data objects: must come after the post-data boundary */
                              20186                 :           5709 :                 addObjectDependency(dobj, postDataBound->dumpId);
                              20187                 :           5709 :                 break;
                              20188                 :          29307 :             case DO_RULE:
                              20189                 :                :                 /* Rules are post-data, but only if dumped separately */
                              20190         [ +  + ]:          29307 :                 if (((RuleInfo *) dobj)->separate)
                              20191                 :            651 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20192                 :          29307 :                 break;
                              20193                 :           2517 :             case DO_CONSTRAINT:
                              20194                 :                :             case DO_FK_CONSTRAINT:
                              20195                 :                :                 /* Constraints are post-data, but only if dumped separately */
                              20196         [ +  + ]:           2517 :                 if (((ConstraintInfo *) dobj)->separate)
                              20197                 :           1809 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20198                 :           2517 :                 break;
                              20199                 :            189 :             case DO_PRE_DATA_BOUNDARY:
                              20200                 :                :                 /* nothing to do */
                              20201                 :            189 :                 break;
                              20202                 :            189 :             case DO_POST_DATA_BOUNDARY:
                              20203                 :                :                 /* must come after the pre-data boundary */
                              20204                 :            189 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              20205                 :            189 :                 break;
  249 jdavis@postgresql.or    20206                 :           3295 :             case DO_REL_STATS:
                              20207                 :                :                 /* stats section varies by parent object type, DATA or POST */
  213                         20208         [ +  + ]:           3295 :                 if (((RelStatsInfo *) dobj)->section == SECTION_DATA)
                              20209                 :                :                 {
  249                         20210                 :           2118 :                     addObjectDependency(dobj, preDataBound->dumpId);
                              20211                 :           2118 :                     addObjectDependency(postDataBound, dobj->dumpId);
                              20212                 :                :                 }
                              20213                 :                :                 else
                              20214                 :           1177 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20215                 :           3295 :                 break;
                              20216                 :                :         }
                              20217                 :                :     }
 4872 tgl@sss.pgh.pa.us       20218                 :            189 : }
                              20219                 :                : 
                              20220                 :                : 
                              20221                 :                : /*
                              20222                 :                :  * BuildArchiveDependencies - create dependency data for archive TOC entries
                              20223                 :                :  *
                              20224                 :                :  * The raw dependency data obtained by getDependencies() is not terribly
                              20225                 :                :  * useful in an archive dump, because in many cases there are dependency
                              20226                 :                :  * chains linking through objects that don't appear explicitly in the dump.
                              20227                 :                :  * For example, a view will depend on its _RETURN rule while the _RETURN rule
                              20228                 :                :  * will depend on other objects --- but the rule will not appear as a separate
                              20229                 :                :  * object in the dump.  We need to adjust the view's dependencies to include
                              20230                 :                :  * whatever the rule depends on that is included in the dump.
                              20231                 :                :  *
                              20232                 :                :  * Just to make things more complicated, there are also "special" dependencies
                              20233                 :                :  * such as the dependency of a TABLE DATA item on its TABLE, which we must
                              20234                 :                :  * not rearrange because pg_restore knows that TABLE DATA only depends on
                              20235                 :                :  * its table.  In these cases we must leave the dependencies strictly as-is
                              20236                 :                :  * even if they refer to not-to-be-dumped objects.
                              20237                 :                :  *
                              20238                 :                :  * To handle this, the convention is that "special" dependencies are created
                              20239                 :                :  * during ArchiveEntry calls, and an archive TOC item that has any such
                              20240                 :                :  * entries will not be touched here.  Otherwise, we recursively search the
                              20241                 :                :  * DumpableObject data structures to build the correct dependencies for each
                              20242                 :                :  * archive TOC item.
                              20243                 :                :  */
                              20244                 :                : static void
                              20245                 :             58 : BuildArchiveDependencies(Archive *fout)
                              20246                 :                : {
                              20247                 :             58 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                              20248                 :                :     TocEntry   *te;
                              20249                 :                : 
                              20250                 :                :     /* Scan all TOC entries in the archive */
                              20251         [ +  + ]:           6642 :     for (te = AH->toc->next; te != AH->toc; te = te->next)
                              20252                 :                :     {
                              20253                 :                :         DumpableObject *dobj;
                              20254                 :                :         DumpId     *dependencies;
                              20255                 :                :         int         nDeps;
                              20256                 :                :         int         allocDeps;
                              20257                 :                : 
                              20258                 :                :         /* No need to process entries that will not be dumped */
                              20259         [ +  + ]:           6584 :         if (te->reqs == 0)
                              20260                 :           3224 :             continue;
                              20261                 :                :         /* Ignore entries that already have "special" dependencies */
                              20262         [ +  + ]:           6571 :         if (te->nDeps > 0)
                              20263                 :           2775 :             continue;
                              20264                 :                :         /* Otherwise, look up the item's original DumpableObject, if any */
                              20265                 :           3796 :         dobj = findObjectByDumpId(te->dumpId);
                              20266         [ +  + ]:           3796 :         if (dobj == NULL)
                              20267                 :            344 :             continue;
                              20268                 :                :         /* No work if it has no dependencies */
                              20269         [ +  + ]:           3452 :         if (dobj->nDeps <= 0)
                              20270                 :             92 :             continue;
                              20271                 :                :         /* Set up work array */
                              20272                 :           3360 :         allocDeps = 64;
                              20273                 :           3360 :         dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
                              20274                 :           3360 :         nDeps = 0;
                              20275                 :                :         /* Recursively find all dumpable dependencies */
                              20276                 :           3360 :         findDumpableDependencies(AH, dobj,
                              20277                 :                :                                  &dependencies, &nDeps, &allocDeps);
                              20278                 :                :         /* And save 'em ... */
                              20279         [ +  + ]:           3360 :         if (nDeps > 0)
                              20280                 :                :         {
                              20281                 :           2491 :             dependencies = (DumpId *) pg_realloc(dependencies,
                              20282                 :                :                                                  nDeps * sizeof(DumpId));
                              20283                 :           2491 :             te->dependencies = dependencies;
                              20284                 :           2491 :             te->nDeps = nDeps;
                              20285                 :                :         }
                              20286                 :                :         else
                              20287                 :            869 :             free(dependencies);
                              20288                 :                :     }
                              20289                 :             58 : }
                              20290                 :                : 
                              20291                 :                : /* Recursive search subroutine for BuildArchiveDependencies */
                              20292                 :                : static void
 1720 peter@eisentraut.org    20293                 :           8252 : findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
                              20294                 :                :                          DumpId **dependencies, int *nDeps, int *allocDeps)
                              20295                 :                : {
                              20296                 :                :     int         i;
                              20297                 :                : 
                              20298                 :                :     /*
                              20299                 :                :      * Ignore section boundary objects: if we search through them, we'll
                              20300                 :                :      * report lots of bogus dependencies.
                              20301                 :                :      */
 4872 tgl@sss.pgh.pa.us       20302         [ +  + ]:           8252 :     if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
                              20303         [ +  + ]:           8233 :         dobj->objType == DO_POST_DATA_BOUNDARY)
                              20304                 :           1387 :         return;
                              20305                 :                : 
                              20306         [ +  + ]:          17017 :     for (i = 0; i < dobj->nDeps; i++)
                              20307                 :                :     {
                              20308                 :          10152 :         DumpId      depid = dobj->dependencies[i];
                              20309                 :                : 
                              20310         [ +  + ]:          10152 :         if (TocIDRequired(AH, depid) != 0)
                              20311                 :                :         {
                              20312                 :                :             /* Object will be dumped, so just reference it as a dependency */
                              20313         [ -  + ]:           5260 :             if (*nDeps >= *allocDeps)
                              20314                 :                :             {
 4872 tgl@sss.pgh.pa.us       20315                 :UBC           0 :                 *allocDeps *= 2;
                              20316                 :              0 :                 *dependencies = (DumpId *) pg_realloc(*dependencies,
 3050                         20317                 :              0 :                                                       *allocDeps * sizeof(DumpId));
                              20318                 :                :             }
 4872 tgl@sss.pgh.pa.us       20319                 :CBC        5260 :             (*dependencies)[*nDeps] = depid;
                              20320                 :           5260 :             (*nDeps)++;
                              20321                 :                :         }
                              20322                 :                :         else
                              20323                 :                :         {
                              20324                 :                :             /*
                              20325                 :                :              * Object will not be dumped, so recursively consider its deps. We
                              20326                 :                :              * rely on the assumption that sortDumpableObjects already broke
                              20327                 :                :              * any dependency loops, else we might recurse infinitely.
                              20328                 :                :              */
                              20329                 :           4892 :             DumpableObject *otherdobj = findObjectByDumpId(depid);
                              20330                 :                : 
                              20331         [ +  - ]:           4892 :             if (otherdobj)
                              20332                 :           4892 :                 findDumpableDependencies(AH, otherdobj,
                              20333                 :                :                                          dependencies, nDeps, allocDeps);
                              20334                 :                :         }
                              20335                 :                :     }
                              20336                 :                : }
                              20337                 :                : 
                              20338                 :                : 
                              20339                 :                : /*
                              20340                 :                :  * getFormattedTypeName - retrieve a nicely-formatted type name for the
                              20341                 :                :  * given type OID.
                              20342                 :                :  *
                              20343                 :                :  * This does not guarantee to schema-qualify the output, so it should not
                              20344                 :                :  * be used to create the target object name for CREATE or ALTER commands.
                              20345                 :                :  *
                              20346                 :                :  * Note that the result is cached and must not be freed by the caller.
                              20347                 :                :  */
                              20348                 :                : static const char *
 5012 rhaas@postgresql.org    20349                 :           2300 : getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
                              20350                 :                : {
                              20351                 :                :     TypeInfo   *typeInfo;
                              20352                 :                :     char       *result;
                              20353                 :                :     PQExpBuffer query;
                              20354                 :                :     PGresult   *res;
                              20355                 :                : 
 7996 tgl@sss.pgh.pa.us       20356         [ -  + ]:           2300 :     if (oid == 0)
                              20357                 :                :     {
 2062 tgl@sss.pgh.pa.us       20358         [ #  # ]:UBC           0 :         if ((opts & zeroAsStar) != 0)
 1510                         20359                 :              0 :             return "*";
 8571                         20360         [ #  # ]:              0 :         else if ((opts & zeroAsNone) != 0)
 1510                         20361                 :              0 :             return "NONE";
                              20362                 :                :     }
                              20363                 :                : 
                              20364                 :                :     /* see if we have the result cached in the type's TypeInfo record */
 1518 tgl@sss.pgh.pa.us       20365                 :CBC        2300 :     typeInfo = findTypeByOid(oid);
                              20366   [ +  -  +  + ]:           2300 :     if (typeInfo && typeInfo->ftypname)
 1510                         20367                 :           1833 :         return typeInfo->ftypname;
                              20368                 :                : 
 8571                         20369                 :            467 :     query = createPQExpBuffer();
 3302                         20370                 :            467 :     appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
                              20371                 :                :                       oid);
                              20372                 :                : 
 5002 rhaas@postgresql.org    20373                 :            467 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              20374                 :                : 
                              20375                 :                :     /* result of format_type is already quoted */
 3302 tgl@sss.pgh.pa.us       20376                 :            467 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              20377                 :                : 
 8571                         20378                 :            467 :     PQclear(res);
                              20379                 :            467 :     destroyPQExpBuffer(query);
                              20380                 :                : 
                              20381                 :                :     /*
                              20382                 :                :      * Cache the result for re-use in later requests, if possible.  If we
                              20383                 :                :      * don't have a TypeInfo for the type, the string will be leaked once the
                              20384                 :                :      * caller is done with it ... but that case really should not happen, so
                              20385                 :                :      * leaking if it does seems acceptable.
                              20386                 :                :      */
 1518                         20387         [ +  - ]:            467 :     if (typeInfo)
 1510                         20388                 :            467 :         typeInfo->ftypname = result;
                              20389                 :                : 
 8571                         20390                 :            467 :     return result;
                              20391                 :                : }
                              20392                 :                : 
                              20393                 :                : /*
                              20394                 :                :  * Return a column list clause for the given relation.
                              20395                 :                :  *
                              20396                 :                :  * Special case: if there are no undropped columns in the relation, return
                              20397                 :                :  * "", not an invalid "()" column list.
                              20398                 :                :  */
                              20399                 :                : static const char *
 4600 andrew@dunslane.net     20400                 :           8206 : fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
                              20401                 :                : {
 8502 bruce@momjian.us        20402                 :           8206 :     int         numatts = ti->numatts;
 8454                         20403                 :           8206 :     char      **attnames = ti->attnames;
                              20404                 :           8206 :     bool       *attisdropped = ti->attisdropped;
 2403 peter@eisentraut.org    20405                 :           8206 :     char       *attgenerated = ti->attgenerated;
                              20406                 :                :     bool        needComma;
                              20407                 :                :     int         i;
                              20408                 :                : 
 4361 heikki.linnakangas@i    20409                 :           8206 :     appendPQExpBufferChar(buffer, '(');
 8487 tgl@sss.pgh.pa.us       20410                 :           8206 :     needComma = false;
 8502 bruce@momjian.us        20411         [ +  + ]:          40018 :     for (i = 0; i < numatts; i++)
                              20412                 :                :     {
 8487 tgl@sss.pgh.pa.us       20413         [ +  + ]:          31812 :         if (attisdropped[i])
                              20414                 :            598 :             continue;
 2403 peter@eisentraut.org    20415         [ +  + ]:          31214 :         if (attgenerated[i])
                              20416                 :           1104 :             continue;
 8487 tgl@sss.pgh.pa.us       20417         [ +  + ]:          30110 :         if (needComma)
 4361 heikki.linnakangas@i    20418                 :          22128 :             appendPQExpBufferStr(buffer, ", ");
                              20419                 :          30110 :         appendPQExpBufferStr(buffer, fmtId(attnames[i]));
 8487 tgl@sss.pgh.pa.us       20420                 :          30110 :         needComma = true;
                              20421                 :                :     }
                              20422                 :                : 
 8355                         20423         [ +  + ]:           8206 :     if (!needComma)
 8221                         20424                 :            224 :         return "";                /* no undropped columns */
                              20425                 :                : 
 4361 heikki.linnakangas@i    20426                 :           7982 :     appendPQExpBufferChar(buffer, ')');
 4600 andrew@dunslane.net     20427                 :           7982 :     return buffer->data;
                              20428                 :                : }
                              20429                 :                : 
                              20430                 :                : /*
                              20431                 :                :  * Check if a reloptions array is nonempty.
                              20432                 :                :  */
                              20433                 :                : static bool
 3586 tgl@sss.pgh.pa.us       20434                 :          13449 : nonemptyReloptions(const char *reloptions)
                              20435                 :                : {
                              20436                 :                :     /* Don't want to print it if it's just "{}" */
                              20437   [ +  -  +  + ]:          13449 :     return (reloptions != NULL && strlen(reloptions) > 2);
                              20438                 :                : }
                              20439                 :                : 
                              20440                 :                : /*
                              20441                 :                :  * Format a reloptions array and append it to the given buffer.
                              20442                 :                :  *
                              20443                 :                :  * "prefix" is prepended to the option names; typically it's "" or "toast.".
                              20444                 :                :  */
                              20445                 :                : static void
 3461 dean.a.rasheed@gmail    20446                 :            208 : appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
                              20447                 :                :                         const char *prefix, Archive *fout)
                              20448                 :                : {
                              20449                 :                :     bool        res;
                              20450                 :                : 
                              20451                 :            208 :     res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
                              20452                 :            208 :                                 fout->std_strings);
                              20453         [ -  + ]:            208 :     if (!res)
 1458 peter@eisentraut.org    20454                 :UBC           0 :         pg_log_warning("could not parse %s array", "reloptions");
 3586 tgl@sss.pgh.pa.us       20455                 :CBC         208 : }
                              20456                 :                : 
                              20457                 :                : /*
                              20458                 :                :  * read_dump_filters - retrieve object identifier patterns from file
                              20459                 :                :  *
                              20460                 :                :  * Parse the specified filter file for include and exclude patterns, and add
                              20461                 :                :  * them to the relevant lists.  If the filename is "-" then filters will be
                              20462                 :                :  * read from STDIN rather than a file.
                              20463                 :                :  */
                              20464                 :                : static void
  698 dgustafsson@postgres    20465                 :             26 : read_dump_filters(const char *filename, DumpOptions *dopt)
                              20466                 :                : {
                              20467                 :                :     FilterStateData fstate;
                              20468                 :                :     char       *objname;
                              20469                 :                :     FilterCommandType comtype;
                              20470                 :                :     FilterObjectType objtype;
                              20471                 :                : 
                              20472                 :             26 :     filter_init(&fstate, filename, exit_nicely);
                              20473                 :                : 
                              20474         [ +  + ]:             84 :     while (filter_read_item(&fstate, &objname, &comtype, &objtype))
                              20475                 :                :     {
                              20476         [ +  + ]:             33 :         if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
                              20477                 :                :         {
                              20478   [ -  -  +  +  :             17 :             switch (objtype)
                                        +  +  +  - ]
                              20479                 :                :             {
  698 dgustafsson@postgres    20480                 :UBC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              20481                 :              0 :                     break;
                              20482                 :              0 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              20483                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              20484                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              20485                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              20486                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              20487                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
  697                         20488                 :              0 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              20489                 :                :                                         "include",
                              20490                 :                :                                         filter_object_type_name(objtype));
  698                         20491                 :              0 :                     exit_nicely(1);
                              20492                 :                :                     break;      /* unreachable */
                              20493                 :                : 
  698 dgustafsson@postgres    20494                 :CBC           1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              20495                 :              1 :                     simple_string_list_append(&extension_include_patterns, objname);
                              20496                 :              1 :                     break;
                              20497                 :              1 :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
                              20498                 :              1 :                     simple_string_list_append(&foreign_servers_include_patterns, objname);
                              20499                 :              1 :                     break;
                              20500                 :              1 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              20501                 :              1 :                     simple_string_list_append(&schema_include_patterns, objname);
                              20502                 :              1 :                     dopt->include_everything = false;
                              20503                 :              1 :                     break;
                              20504                 :             13 :                 case FILTER_OBJECT_TYPE_TABLE:
                              20505                 :             13 :                     simple_string_list_append(&table_include_patterns, objname);
                              20506                 :             13 :                     dopt->include_everything = false;
                              20507                 :             13 :                     break;
                              20508                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              20509                 :              1 :                     simple_string_list_append(&table_include_patterns_and_children,
                              20510                 :                :                                               objname);
                              20511                 :              1 :                     dopt->include_everything = false;
                              20512                 :              1 :                     break;
                              20513                 :                :             }
                              20514                 :                :         }
                              20515         [ +  + ]:             16 :         else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
                              20516                 :                :         {
                              20517   [ -  +  +  +  :              9 :             switch (objtype)
                                        +  +  +  +  
                                                 - ]
                              20518                 :                :             {
  698 dgustafsson@postgres    20519                 :UBC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              20520                 :              0 :                     break;
  698 dgustafsson@postgres    20521                 :CBC           1 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              20522                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              20523                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              20524                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
                              20525                 :                :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
  697                         20526                 :              1 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              20527                 :                :                                         "exclude",
                              20528                 :                :                                         filter_object_type_name(objtype));
  698                         20529                 :              1 :                     exit_nicely(1);
                              20530                 :                :                     break;
                              20531                 :                : 
  586 dean.a.rasheed@gmail    20532                 :              1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              20533                 :              1 :                     simple_string_list_append(&extension_exclude_patterns, objname);
                              20534                 :              1 :                     break;
  698 dgustafsson@postgres    20535                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              20536                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns,
                              20537                 :                :                                               objname);
                              20538                 :              1 :                     break;
                              20539                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              20540                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns_and_children,
                              20541                 :                :                                               objname);
                              20542                 :              1 :                     break;
                              20543                 :              2 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              20544                 :              2 :                     simple_string_list_append(&schema_exclude_patterns, objname);
                              20545                 :              2 :                     break;
                              20546                 :              2 :                 case FILTER_OBJECT_TYPE_TABLE:
                              20547                 :              2 :                     simple_string_list_append(&table_exclude_patterns, objname);
                              20548                 :              2 :                     break;
                              20549                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              20550                 :              1 :                     simple_string_list_append(&table_exclude_patterns_and_children,
                              20551                 :                :                                               objname);
                              20552                 :              1 :                     break;
                              20553                 :                :             }
                              20554                 :                :         }
                              20555                 :                :         else
                              20556                 :                :         {
                              20557         [ -  + ]:              7 :             Assert(comtype == FILTER_COMMAND_TYPE_NONE);
                              20558         [ -  + ]:              7 :             Assert(objtype == FILTER_OBJECT_TYPE_NONE);
                              20559                 :                :         }
                              20560                 :                : 
                              20561         [ +  + ]:             32 :         if (objname)
                              20562                 :             25 :             free(objname);
                              20563                 :                :     }
                              20564                 :                : 
                              20565                 :             22 :     filter_free(&fstate);
                              20566                 :             22 : }
        

Generated by: LCOV version 2.4-beta