LCOV - differential code coverage report
Current view: top level - src/bin/pg_dump - pg_dump.c (source / functions) Coverage Total Hit UNC LBC UBC GBC GNC CBC DCB
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 90.2 % 8346 7531 4 2 809 4 35 7492 3
Current Date: 2025-09-06 07:49:51 +0900 Functions: 97.9 % 188 184 4 5 179
Baseline: lcov-20250906-005545-baseline Branches: 77.0 % 3914 3014 10 1 889 7 26 2981
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(1,7] days: 75.0 % 8 6 2 6
(7,30] days: 80.0 % 15 12 3 12
(30,360] days: 93.8 % 775 727 2 46 29 698
(360..) days: 89.9 % 7548 6786 2 760 4 6782
Function coverage date bins:
(30,360] days: 100.0 % 6 6 6
(360..) days: 97.8 % 182 178 4 5 173
Branch coverage date bins:
(1,7] days: 50.0 % 4 2 2 2
(7,30] days: 70.0 % 10 7 3 7
(30,360] days: 82.4 % 567 467 8 92 24 443
(360..) days: 76.1 % 3333 2538 1 794 7 2531

 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
 8520 tgl@sss.pgh.pa.us         421                 :CBC         293 : main(int argc, char **argv)
                                422                 :                : {
                                423                 :                :     int         c;
                                424                 :            293 :     const char *filename = NULL;
                                425                 :            293 :     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 */
 2350 peter@eisentraut.org      435                 :            293 :     bool        g_verbose = false;
 3980 alvherre@alvh.no-ip.      436                 :            293 :     const char *dumpencoding = NULL;
 3946 simon@2ndQuadrant.co      437                 :            293 :     const char *dumpsnapshot = NULL;
 3980 alvherre@alvh.no-ip.      438                 :            293 :     char       *use_role = NULL;
 4549 andrew@dunslane.net       439                 :            293 :     int         numWorkers = 1;
 8520 tgl@sss.pgh.pa.us         440                 :            293 :     int         plainText = 0;
 5340 heikki.linnakangas@i      441                 :            293 :     ArchiveFormat archiveFormat = archUnknown;
                                442                 :                :     ArchiveMode archiveMode;
 1009 michael@paquier.xyz       443                 :            293 :     pg_compress_specification compression_spec = {0};
                                444                 :            293 :     char       *compression_detail = NULL;
                                445                 :            293 :     char       *compression_algorithm_str = "none";
                                446                 :            293 :     char       *error_detail = NULL;
                                447                 :            293 :     bool        user_compression_defined = false;
  731 nathan@postgresql.or      448                 :            293 :     DataDirSyncMethod sync_method = DATA_DIR_SYNC_METHOD_FSYNC;
  285                           449                 :            293 :     bool        data_only = false;
                                450                 :            293 :     bool        schema_only = false;
  198 jdavis@postgresql.or      451                 :            293 :     bool        statistics_only = false;
  165                           452                 :            293 :     bool        with_statistics = false;
  198                           453                 :            293 :     bool        no_data = false;
                                454                 :            293 :     bool        no_schema = false;
                                455                 :            293 :     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                 :                : 
 2350 peter@eisentraut.org      545                 :            293 :     pg_logging_init(argv[0]);
                                546                 :            293 :     pg_logging_set_level(PG_LOG_WARNING);
 6113 peter_e@gmx.net           547                 :            293 :     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                 :                :      */
 4549 andrew@dunslane.net       553                 :            293 :     init_parallel_dump_utils();
                                554                 :                : 
 8191 bruce@momjian.us          555                 :            293 :     progname = get_progname(argv[0]);
                                556                 :                : 
 8520 tgl@sss.pgh.pa.us         557         [ +  - ]:            293 :     if (argc > 1)
                                558                 :                :     {
                                559   [ +  +  -  + ]:            293 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                                560                 :                :         {
                                561                 :              1 :             help(progname);
 4951 rhaas@postgresql.org      562                 :              1 :             exit_nicely(0);
                                563                 :                :         }
 8520 tgl@sss.pgh.pa.us         564   [ +  +  +  + ]:            292 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                                565                 :                :         {
                                566                 :             62 :             puts("pg_dump (PostgreSQL) " PG_VERSION);
 4951 rhaas@postgresql.org      567                 :             62 :             exit_nicely(0);
                                568                 :                :         }
                                569                 :                :     }
                                570                 :                : 
 3891 tgl@sss.pgh.pa.us         571                 :            230 :     InitDumpOptions(&dopt);
                                572                 :                : 
  198 jdavis@postgresql.or      573                 :           1276 :     while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxXZ:",
 8279 peter_e@gmx.net           574         [ +  + ]:           1276 :                             long_options, &optindex)) != -1)
                                575                 :                :     {
 8520 tgl@sss.pgh.pa.us         576   [ +  +  +  +  :           1054 :         switch (c)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     -  +  +  +  +  
                                     +  +  +  -  +  
                                     +  +  +  +  +  
                                     +  +  -  +  +  
                                     +  +  +  +  +  
                                              +  + ]
                                577                 :                :         {
                                578                 :              9 :             case 'a':           /* Dump data only */
  285 nathan@postgresql.or      579                 :              9 :                 data_only = true;
 8520 tgl@sss.pgh.pa.us         580                 :              9 :                 break;
                                581                 :                : 
 1006 peter@eisentraut.org      582                 :              1 :             case 'b':           /* Dump LOs */
                                583                 :              1 :                 dopt.outputLOs = true;
 8520 tgl@sss.pgh.pa.us         584                 :              1 :                 break;
                                585                 :                : 
 1006 peter@eisentraut.org      586                 :              2 :             case 'B':           /* Don't dump LOs */
                                587                 :              2 :                 dopt.dontOutputLOs = true;
 3203 sfrost@snowman.net        588                 :              2 :                 break;
                                589                 :                : 
 7266 bruce@momjian.us          590                 :              6 :             case 'c':           /* clean (i.e., drop) schema prior to create */
 3891 tgl@sss.pgh.pa.us         591                 :              6 :                 dopt.outputClean = 1;
 8520                           592                 :              6 :                 break;
                                593                 :                : 
                                594                 :             29 :             case 'C':           /* Create DB */
 3891                           595                 :             29 :                 dopt.outputCreateDB = 1;
 8520                           596                 :             29 :                 break;
                                597                 :                : 
 4576 heikki.linnakangas@i      598                 :              5 :             case 'd':           /* database name */
 1808 tgl@sss.pgh.pa.us         599                 :              5 :                 dopt.cparams.dbname = pg_strdup(optarg);
 4576 heikki.linnakangas@i      600                 :              5 :                 break;
                                601                 :                : 
 1620 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                 :                : 
 7363 bruce@momjian.us          607                 :              2 :             case 'E':           /* Dump encoding */
 4712                           608                 :              2 :                 dumpencoding = pg_strdup(optarg);
 7363                           609                 :              2 :                 break;
                                610                 :                : 
 8520 tgl@sss.pgh.pa.us         611                 :            183 :             case 'f':
 4712 bruce@momjian.us          612                 :            183 :                 filename = pg_strdup(optarg);
 8520 tgl@sss.pgh.pa.us         613                 :            183 :                 break;
                                614                 :                : 
                                615                 :            111 :             case 'F':
 4712 bruce@momjian.us          616                 :            111 :                 format = pg_strdup(optarg);
 8520 tgl@sss.pgh.pa.us         617                 :            111 :                 break;
                                618                 :                : 
                                619                 :             34 :             case 'h':           /* server host */
 1808                           620                 :             34 :                 dopt.cparams.pghost = pg_strdup(optarg);
 8520                           621                 :             34 :                 break;
                                622                 :                : 
 4549 andrew@dunslane.net       623                 :             12 :             case 'j':           /* number of dump jobs */
 1505 michael@paquier.xyz       624         [ +  + ]:             12 :                 if (!option_parse_int(optarg, "-j/--jobs", 1,
                                625                 :                :                                       PG_MAX_JOBS,
                                626                 :                :                                       &numWorkers))
                                627                 :              1 :                     exit_nicely(1);
 4549 andrew@dunslane.net       628                 :             11 :                 break;
                                629                 :                : 
 6907 tgl@sss.pgh.pa.us         630                 :             17 :             case 'n':           /* include schema(s) */
                                631                 :             17 :                 simple_string_list_append(&schema_include_patterns, optarg);
 3891                           632                 :             17 :                 dopt.include_everything = false;
 6907                           633                 :             17 :                 break;
                                634                 :                : 
                                635                 :              1 :             case 'N':           /* exclude schema(s) */
                                636                 :              1 :                 simple_string_list_append(&schema_exclude_patterns, optarg);
 8241 bruce@momjian.us          637                 :              1 :                 break;
                                638                 :                : 
 8520 tgl@sss.pgh.pa.us         639                 :              2 :             case 'O':           /* Don't reconnect to match owner */
 3891                           640                 :              2 :                 dopt.outputNoOwner = 1;
 8520                           641                 :              2 :                 break;
                                642                 :                : 
                                643                 :             73 :             case 'p':           /* server port */
 1808                           644                 :             73 :                 dopt.cparams.pgport = pg_strdup(optarg);
 8520                           645                 :             73 :                 break;
                                646                 :                : 
 8019                           647                 :              2 :             case 'R':
                                648                 :                :                 /* no-op, still accepted for backwards compatibility */
 8520                           649                 :              2 :                 break;
                                650                 :                : 
                                651                 :              7 :             case 's':           /* dump schema only */
  285 nathan@postgresql.or      652                 :              7 :                 schema_only = true;
 8520 tgl@sss.pgh.pa.us         653                 :              7 :                 break;
                                654                 :                : 
 7266 bruce@momjian.us          655                 :              1 :             case 'S':           /* Username for superuser in plain text output */
 3891 tgl@sss.pgh.pa.us         656                 :              1 :                 dopt.outputSuperuser = pg_strdup(optarg);
 8520                           657                 :              1 :                 break;
                                658                 :                : 
 6907                           659                 :              8 :             case 't':           /* include table(s) */
                                660                 :              8 :                 simple_string_list_append(&table_include_patterns, optarg);
 3891                           661                 :              8 :                 dopt.include_everything = false;
 6907                           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                 :                : 
 8520                           668                 :             36 :             case 'U':
 1808                           669                 :             36 :                 dopt.cparams.username = pg_strdup(optarg);
 8520                           670                 :             36 :                 break;
                                671                 :                : 
                                672                 :              6 :             case 'v':           /* verbose */
                                673                 :              6 :                 g_verbose = true;
 1815                           674                 :              6 :                 pg_logging_increase_verbosity();
 8520                           675                 :              6 :                 break;
                                676                 :                : 
 6036 peter_e@gmx.net           677                 :              1 :             case 'w':
 1808 tgl@sss.pgh.pa.us         678                 :              1 :                 dopt.cparams.promptPassword = TRI_NO;
 6036 peter_e@gmx.net           679                 :              1 :                 break;
                                680                 :                : 
 8520 tgl@sss.pgh.pa.us         681                 :UBC           0 :             case 'W':
 1808                           682                 :              0 :                 dopt.cparams.promptPassword = TRI_YES;
 8520                           683                 :              0 :                 break;
                                684                 :                : 
 8520 tgl@sss.pgh.pa.us         685                 :CBC           2 :             case 'x':           /* skip ACL dump */
 3891                           686                 :              2 :                 dopt.aclsSkip = true;
 8520                           687                 :              2 :                 break;
                                688                 :                : 
 1009 michael@paquier.xyz       689                 :             15 :             case 'Z':           /* Compression */
                                690                 :             15 :                 parse_compress_options(optarg, &compression_algorithm_str,
                                691                 :                :                                        &compression_detail);
                                692                 :             15 :                 user_compression_defined = true;
 8520 tgl@sss.pgh.pa.us         693                 :             15 :                 break;
                                694                 :                : 
                                695                 :            128 :             case 0:
                                696                 :                :                 /* This covers the long options. */
                                697                 :            128 :                 break;
                                698                 :                : 
 6088                           699                 :              2 :             case 2:             /* lock-wait-timeout */
 3891                           700                 :              2 :                 dopt.lockWaitTimeout = pg_strdup(optarg);
 6257                           701                 :              2 :                 break;
                                702                 :                : 
 6088                           703                 :              3 :             case 3:             /* SET ROLE */
 4712 bruce@momjian.us          704                 :              3 :                 use_role = pg_strdup(optarg);
 6088 tgl@sss.pgh.pa.us         705                 :              3 :                 break;
                                706                 :                : 
 4836 bruce@momjian.us          707                 :              1 :             case 4:             /* exclude table(s) data */
 5015 andrew@dunslane.net       708                 :              1 :                 simple_string_list_append(&tabledata_exclude_patterns, optarg);
                                709                 :              1 :                 break;
                                710                 :                : 
 5013                           711                 :              6 :             case 5:             /* section */
 3891 tgl@sss.pgh.pa.us         712                 :              6 :                 set_dump_section(optarg, &dopt.dumpSections);
 5013 andrew@dunslane.net       713                 :              6 :                 break;
                                714                 :                : 
 3946 simon@2ndQuadrant.co      715                 :UBC           0 :             case 6:             /* snapshot */
                                716                 :              0 :                 dumpsnapshot = pg_strdup(optarg);
                                717                 :              0 :                 break;
                                718                 :                : 
 3090 andrew@dunslane.net       719                 :CBC         138 :             case 7:             /* no-sync */
                                720                 :            138 :                 dosync = false;
                                721                 :            138 :                 break;
                                722                 :                : 
 2392                           723                 :              1 :             case 8:
                                724                 :              1 :                 have_extra_float_digits = true;
 1505 michael@paquier.xyz       725         [ +  - ]:              1 :                 if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
                                726                 :                :                                       &extra_float_digits))
 2392 andrew@dunslane.net       727                 :              1 :                     exit_nicely(1);
 2392 andrew@dunslane.net       728                 :UBC           0 :                 break;
                                729                 :                : 
 2375 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 */
 1505 michael@paquier.xyz       741         [ +  + ]:              2 :                 if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
                                742                 :                :                                       &dopt.dump_inserts))
 2375 alvherre@alvh.no-ip.      743                 :              1 :                     exit_nicely(1);
                                744                 :              1 :                 break;
                                745                 :                : 
 1991                           746                 :              4 :             case 11:            /* include foreign data */
                                747                 :              4 :                 simple_string_list_append(&foreign_servers_include_patterns,
                                748                 :                :                                           optarg);
                                749                 :              4 :                 break;
                                750                 :                : 
  907 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                 :                : 
  731 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                 :                : 
  647 dgustafsson@postgres      772                 :CBC          26 :             case 16:            /* read object filters from file */
                                773                 :             26 :                 read_dump_filters(optarg, &dopt);
                                774                 :             22 :                 break;
                                775                 :                : 
  535 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                 :                : 
  198 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                 :                : 
  165                           797                 :             87 :             case 22:
                                798                 :             87 :                 with_statistics = true;
                                799                 :             87 :                 break;
                                800                 :                : 
   26 nathan@postgresql.or      801                 :             26 :             case 25:
                                802                 :             26 :                 dopt.restrict_key = pg_strdup(optarg);
                                803                 :             26 :                 break;
                                804                 :                : 
 8520 tgl@sss.pgh.pa.us         805                 :              1 :             default:
                                806                 :                :                 /* getopt_long already emitted a complaint */
 1247                           807                 :              1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 4951 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                 :                :      */
 1808 tgl@sss.pgh.pa.us         816   [ +  +  +  - ]:            222 :     if (optind < argc && dopt.cparams.dbname == NULL)
                                817                 :            186 :         dopt.cparams.dbname = argv[optind++];
                                818                 :                : 
                                819                 :                :     /* Complain if any arguments remain */
 5503                           820         [ +  + ]:            222 :     if (optind < argc)
                                821                 :                :     {
 2350 peter@eisentraut.org      822                 :              1 :         pg_log_error("too many command-line arguments (first is \"%s\")",
                                823                 :                :                      argv[optind]);
 1247 tgl@sss.pgh.pa.us         824                 :              1 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 4951 rhaas@postgresql.org      825                 :              1 :         exit_nicely(1);
                                826                 :                :     }
                                827                 :                : 
                                828                 :                :     /* --column-inserts implies --inserts */
 2375 alvherre@alvh.no-ip.      829   [ +  +  +  - ]:            221 :     if (dopt.column_inserts && dopt.dump_inserts == 0)
                                830                 :              1 :         dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT;
                                831                 :                : 
                                832                 :                :     /* reject conflicting "-only" options */
  285 nathan@postgresql.or      833   [ +  +  +  + ]:            221 :     if (data_only && schema_only)
 1247 tgl@sss.pgh.pa.us         834                 :              1 :         pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
  198 jdavis@postgresql.or      835   [ +  +  +  + ]:            220 :     if (schema_only && statistics_only)
                                836                 :              1 :         pg_fatal("options -s/--schema-only and --statistics-only cannot be used together");
                                837   [ +  +  +  + ]:            219 :     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   [ +  +  -  + ]:            218 :     if (data_only && no_data)
  198 jdavis@postgresql.or      842                 :UBC           0 :         pg_fatal("options -a/--data-only and --no-data cannot be used together");
  198 jdavis@postgresql.or      843   [ +  +  -  + ]:CBC         218 :     if (schema_only && no_schema)
  198 jdavis@postgresql.or      844                 :UBC           0 :         pg_fatal("options -s/--schema-only and --no-schema cannot be used together");
  198 jdavis@postgresql.or      845   [ +  +  +  + ]:CBC         218 :     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 */
  165                           849   [ +  +  -  + ]:            217 :     if (with_statistics && no_statistics)
   35 jdavis@postgresql.or      850                 :UBC           0 :         pg_fatal("options --statistics and --no-statistics cannot be used together");
                                851                 :                : 
                                852                 :                :     /* reject conflicting "-only" options */
   35 jdavis@postgresql.or      853   [ +  +  -  + ]:CBC         217 :     if (data_only && with_statistics)
   36 jdavis@postgresql.or      854                 :UBC           0 :         pg_fatal("options %s and %s cannot be used together",
                                855                 :                :                  "-a/--data-only", "--statistics");
   35 jdavis@postgresql.or      856   [ +  +  +  + ]:CBC         217 :     if (schema_only && with_statistics)
   36                           857                 :              1 :         pg_fatal("options %s and %s cannot be used together",
                                858                 :                :                  "-s/--schema-only", "--statistics");
                                859                 :                : 
  285 nathan@postgresql.or      860   [ +  +  +  + ]:            216 :     if (schema_only && foreign_servers_include_patterns.head != NULL)
 1247 tgl@sss.pgh.pa.us         861                 :              1 :         pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
                                862                 :                : 
 1991 alvherre@alvh.no-ip.      863   [ +  +  +  + ]:            215 :     if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
 1247 tgl@sss.pgh.pa.us         864                 :              1 :         pg_fatal("option --include-foreign-data is not supported with parallel backup");
                                865                 :                : 
  285 nathan@postgresql.or      866   [ +  +  +  + ]:            214 :     if (data_only && dopt.outputClean)
 1247 tgl@sss.pgh.pa.us         867                 :              1 :         pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
                                868                 :                : 
 3891                           869   [ +  +  +  + ]:            213 :     if (dopt.if_exists && !dopt.outputClean)
 1247                           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                 :                :      */
  165 jdavis@postgresql.or      877   [ +  +  +  +  :            212 :     dopt.dumpData = ((dopt.dumpData && !schema_only && !statistics_only) ||
                                              -  + ]
   35                           878   [ +  -  +  + ]:            424 :                      data_only) && !no_data;
  165                           879   [ +  +  +  +  :            212 :     dopt.dumpSchema = ((dopt.dumpSchema && !data_only && !statistics_only) ||
                                              -  + ]
   35                           880   [ +  -  +  + ]:            424 :                        schema_only) && !no_schema;
  165                           881   [ -  -  -  -  :            212 :     dopt.dumpStatistics = ((dopt.dumpStatistics && !schema_only && !data_only) ||
                                              +  + ]
                                882   [ -  +  +  +  :            424 :                            (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                 :                :      */
 2375 alvherre@alvh.no-ip.      889   [ +  +  +  - ]:            212 :     if (dopt.do_nothing && dopt.dump_inserts == 0)
 1247 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 */
 5340 heikki.linnakangas@i      893                 :            211 :     archiveFormat = parseArchiveFormat(format, &archiveMode);
                                894                 :                : 
                                895                 :                :     /* archiveFormat specific setup */
                                896         [ +  + ]:            210 :     if (archiveFormat == archNull)
                                897                 :                :     {
 6743 bruce@momjian.us          898                 :            154 :         plainText = 1;
                                899                 :                : 
                                900                 :                :         /*
                                901                 :                :          * If you don't provide a restrict key, one will be appointed for you.
                                902                 :                :          */
   26 nathan@postgresql.or      903         [ +  + ]:            154 :         if (!dopt.restrict_key)
                                904                 :            128 :             dopt.restrict_key = generate_restrict_key();
                                905         [ -  + ]:            154 :         if (!dopt.restrict_key)
   26 nathan@postgresql.or      906                 :UBC           0 :             pg_fatal("could not generate restrict key");
   26 nathan@postgresql.or      907         [ -  + ]:CBC         154 :         if (!valid_restrict_key(dopt.restrict_key))
   26 nathan@postgresql.or      908                 :UBC           0 :             pg_fatal("invalid restrict key");
                                909                 :                :     }
   26 nathan@postgresql.or      910         [ -  + ]:CBC          56 :     else if (dopt.restrict_key)
   26 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                 :                :      */
  863 michael@paquier.xyz       918   [ +  +  +  + ]:CBC         210 :     if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
                                919         [ +  + ]:             53 :         !user_compression_defined)
                                920                 :                :     {
                                921                 :                : #ifdef HAVE_LIBZ
                                922                 :             46 :         compression_algorithm_str = "gzip";
                                923                 :                : #else
                                924                 :                :         compression_algorithm_str = "none";
                                925                 :                : #endif
                                926                 :                :     }
                                927                 :                : 
                                928                 :                :     /*
                                929                 :                :      * Compression options
                                930                 :                :      */
 1009                           931         [ +  + ]:            210 :     if (!parse_compress_algorithm(compression_algorithm_str,
                                932                 :                :                                   &compression_algorithm))
                                933                 :              1 :         pg_fatal("unrecognized compression algorithm: \"%s\"",
                                934                 :                :                  compression_algorithm_str);
                                935                 :                : 
                                936                 :            209 :     parse_compress_specification(compression_algorithm, compression_detail,
                                937                 :                :                                  &compression_spec);
                                938                 :            209 :     error_detail = validate_compress_specification(&compression_spec);
                                939         [ +  + ]:            209 :     if (error_detail != NULL)
                                940                 :              3 :         pg_fatal("invalid compression specification: %s",
                                941                 :                :                  error_detail);
                                942                 :                : 
  885 tomas.vondra@postgre      943                 :            206 :     error_detail = supports_compression(compression_spec);
                                944         [ -  + ]:            206 :     if (error_detail != NULL)
  885 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                 :                :      */
  885 tomas.vondra@postgre      952         [ -  + ]:CBC         206 :     if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
  885 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                 :                :      */
 2781 tgl@sss.pgh.pa.us         960         [ +  + ]:CBC         206 :     if (!plainText)
                                961                 :             56 :         dopt.outputCreateDB = 1;
                                962                 :                : 
                                963                 :                :     /* Parallel backup only in the directory archive format so far */
 4549 andrew@dunslane.net       964   [ +  +  +  + ]:            206 :     if (archiveFormat != archDirectory && numWorkers > 1)
 1247 tgl@sss.pgh.pa.us         965                 :              1 :         pg_fatal("parallel backup only supported by the directory format");
                                966                 :                : 
                                967                 :                :     /* Open the output file */
 1009 michael@paquier.xyz       968                 :            205 :     fout = CreateArchive(filename, archiveFormat, compression_spec,
                                969                 :                :                          dosync, archiveMode, setupDumpWorker, sync_method);
                                970                 :                : 
                                971                 :                :     /* Make dump options accessible right away */
 3524 tgl@sss.pgh.pa.us         972                 :            204 :     SetArchiveOptions(fout, &dopt, NULL);
                                973                 :                : 
                                974                 :                :     /* Register the cleanup hook */
 4918 alvherre@alvh.no-ip.      975                 :            204 :     on_exit_close_archive(fout);
                                976                 :                : 
                                977                 :                :     /* Let the archiver know how noisy to be */
 4961 rhaas@postgresql.org      978                 :            204 :     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                 :                :      */
 1362 tgl@sss.pgh.pa.us         985                 :            204 :     fout->minRemoteVersion = 90200;
 4547 heikki.linnakangas@i      986                 :            204 :     fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
                                987                 :                : 
 4549 andrew@dunslane.net       988                 :            204 :     fout->numWorkers = numWorkers;
                                989                 :                : 
                                990                 :                :     /*
                                991                 :                :      * Open the database using the Archiver, so it knows about it. Errors mean
                                992                 :                :      * death.
                                993                 :                :      */
  155                           994                 :            204 :     ConnectDatabaseAhx(fout, &dopt.cparams, false);
 3524 tgl@sss.pgh.pa.us         995                 :            202 :     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                 :                :      */
 3390 magnus@hagander.net      1001         [ +  + ]:            202 :     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                 :                :      */
 1362 tgl@sss.pgh.pa.us        1009                 :            202 :     g_last_builtin_oid = FirstNormalObjectId - 1;
                               1010                 :                : 
 2350 peter@eisentraut.org     1011                 :            202 :     pg_log_info("last built-in OID is %u", g_last_builtin_oid);
                               1012                 :                : 
                               1013                 :                :     /* Expand schema selection patterns into OID lists */
 6907 tgl@sss.pgh.pa.us        1014         [ +  + ]:            202 :     if (schema_include_patterns.head != NULL)
                               1015                 :                :     {
 4961 rhaas@postgresql.org     1016                 :             18 :         expand_schema_name_patterns(fout, &schema_include_patterns,
                               1017                 :                :                                     &schema_include_oids,
                               1018                 :                :                                     strict_names);
 6907 tgl@sss.pgh.pa.us        1019         [ +  + ]:             12 :         if (schema_include_oids.head == NULL)
 1247                          1020                 :              1 :             pg_fatal("no matching schemas were found");
                               1021                 :                :     }
 4961 rhaas@postgresql.org     1022                 :            195 :     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 */
  907 tgl@sss.pgh.pa.us        1028                 :            195 :     expand_table_name_patterns(fout, &table_include_patterns,
                               1029                 :                :                                &table_include_oids,
                               1030                 :                :                                strict_names, false);
                               1031                 :            190 :     expand_table_name_patterns(fout, &table_include_patterns_and_children,
                               1032                 :                :                                &table_include_oids,
                               1033                 :                :                                strict_names, true);
                               1034         [ +  + ]:            190 :     if ((table_include_patterns.head != NULL ||
                               1035         [ +  + ]:            179 :          table_include_patterns_and_children.head != NULL) &&
                               1036         [ +  + ]:             13 :         table_include_oids.head == NULL)
                               1037                 :              2 :         pg_fatal("no matching tables were found");
                               1038                 :                : 
 4960 rhaas@postgresql.org     1039                 :            188 :     expand_table_name_patterns(fout, &table_exclude_patterns,
                               1040                 :                :                                &table_exclude_oids,
                               1041                 :                :                                false, false);
  907 tgl@sss.pgh.pa.us        1042                 :            188 :     expand_table_name_patterns(fout, &table_exclude_patterns_and_children,
                               1043                 :                :                                &table_exclude_oids,
                               1044                 :                :                                false, true);
                               1045                 :                : 
 4960 rhaas@postgresql.org     1046                 :            188 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns,
                               1047                 :                :                                &tabledata_exclude_oids,
                               1048                 :                :                                false, false);
  907 tgl@sss.pgh.pa.us        1049                 :            188 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns_and_children,
                               1050                 :                :                                &tabledata_exclude_oids,
                               1051                 :                :                                false, true);
                               1052                 :                : 
 1991 alvherre@alvh.no-ip.     1053                 :            188 :     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 */
 1620 michael@paquier.xyz      1059         [ +  + ]:            187 :     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)
 1247 tgl@sss.pgh.pa.us        1065                 :              1 :             pg_fatal("no matching extensions were found");
                               1066                 :                :     }
  535 dean.a.rasheed@gmail     1067                 :            186 :     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                 :                :      */
  285 nathan@postgresql.or     1081   [ +  +  +  +  :            186 :     if (dopt.include_everything && dopt.dumpData && !dopt.dontOutputLOs)
                                              +  + ]
 1006 peter@eisentraut.org     1082                 :            121 :         dopt.outputLOs = true;
                               1083                 :                : 
                               1084                 :                :     /*
                               1085                 :                :      * Collect role names so we can map object owner OIDs to names.
                               1086                 :                :      */
 1345 tgl@sss.pgh.pa.us        1087                 :            186 :     collectRoleNames(fout);
                               1088                 :                : 
                               1089                 :                :     /*
                               1090                 :                :      * Now scan the database and create DumpableObject structs for all the
                               1091                 :                :      * objects we intend to dump.
                               1092                 :                :      */
 3524                          1093                 :            186 :     tblinfo = getSchemaData(fout, &numTables);
                               1094                 :                : 
  285 nathan@postgresql.or     1095         [ +  + ]:            185 :     if (dopt.dumpData)
                               1096                 :                :     {
 2482 andres@anarazel.de       1097                 :            145 :         getTableData(&dopt, tblinfo, numTables, 0);
 4570 kgrittn@postgresql.o     1098                 :            145 :         buildMatViewRefreshDependencies(fout);
  285 nathan@postgresql.or     1099         [ +  + ]:            145 :         if (!dopt.dumpSchema)
 6207 tgl@sss.pgh.pa.us        1100                 :              7 :             getTableDataFKConstraints();
                               1101                 :                :     }
                               1102                 :                : 
  285 nathan@postgresql.or     1103   [ +  +  +  + ]:            185 :     if (!dopt.dumpData && dopt.sequence_data)
 2482 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                 :                :      */
   50 nathan@postgresql.or     1113   [ +  +  +  - ]:GNC         185 :     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                 :                :     /*
                               1137                 :                :      * In binary-upgrade mode, we do not have to worry about the actual LO
                               1138                 :                :      * data or the associated metadata that resides in the pg_largeobject and
                               1139                 :                :      * pg_largeobject_metadata tables, respectively.
                               1140                 :                :      *
                               1141                 :                :      * However, we do need to collect LO information as there may be comments
                               1142                 :                :      * or other information on LOs that we do need to dump out.
                               1143                 :                :      */
 1006 peter@eisentraut.org     1144   [ +  +  +  + ]:CBC         185 :     if (dopt.outputLOs || dopt.binary_upgrade)
                               1145                 :            157 :         getLOs(fout);
                               1146                 :                : 
                               1147                 :                :     /*
                               1148                 :                :      * Collect dependency data to assist in ordering the objects.
                               1149                 :                :      */
 4961 rhaas@postgresql.org     1150                 :            185 :     getDependencies(fout);
                               1151                 :                : 
                               1152                 :                :     /*
                               1153                 :                :      * Collect ACLs, comments, and security labels, if wanted.
                               1154                 :                :      */
 1370 tgl@sss.pgh.pa.us        1155         [ +  + ]:            185 :     if (!dopt.aclsSkip)
                               1156                 :            183 :         getAdditionalACLs(fout);
                               1157         [ +  - ]:            185 :     if (!dopt.no_comments)
                               1158                 :            185 :         collectComments(fout);
                               1159         [ +  - ]:            185 :     if (!dopt.no_security_labels)
                               1160                 :            185 :         collectSecLabels(fout);
                               1161                 :                : 
                               1162                 :                :     /* For binary upgrade mode, collect required pg_class information. */
  430 nathan@postgresql.or     1163         [ +  + ]:            185 :     if (dopt.binary_upgrade)
                               1164                 :             36 :         collectBinaryUpgradeClassOids(fout);
                               1165                 :                : 
                               1166                 :                :     /* Collect sequence information. */
  402                          1167                 :            185 :     collectSequences(fout);
                               1168                 :                : 
                               1169                 :                :     /* Lastly, create dummy objects to represent the section boundaries */
 4821 tgl@sss.pgh.pa.us        1170                 :            185 :     boundaryObjs = createBoundaryObjects();
                               1171                 :                : 
                               1172                 :                :     /* Get pointers to all the known DumpableObjects */
                               1173                 :            185 :     getDumpableObjects(&dobjs, &numObjs);
                               1174                 :                : 
                               1175                 :                :     /*
                               1176                 :                :      * Add dummy dependencies to enforce the dump section ordering.
                               1177                 :                :      */
                               1178                 :            185 :     addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
                               1179                 :                : 
                               1180                 :                :     /*
                               1181                 :                :      * Sort the objects into a safe dump order (no forward references).
                               1182                 :                :      *
                               1183                 :                :      * We rely on dependency information to help us determine a safe order, so
                               1184                 :                :      * the initial sort is mostly for cosmetic purposes: we sort by name to
                               1185                 :                :      * ensure that logically identical schemas will dump identically.
                               1186                 :                :      */
 3251                          1187                 :            185 :     sortDumpableObjectsByTypeName(dobjs, numObjs);
                               1188                 :                : 
 4821                          1189                 :            185 :     sortDumpableObjects(dobjs, numObjs,
                               1190                 :            185 :                         boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
                               1191                 :                : 
                               1192                 :                :     /*
                               1193                 :                :      * Create archive TOC entries for all the objects to be dumped, in a safe
                               1194                 :                :      * order.
                               1195                 :                :      */
                               1196                 :                : 
                               1197                 :                :     /*
                               1198                 :                :      * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
                               1199                 :                :      */
 4961 rhaas@postgresql.org     1200                 :            185 :     dumpEncoding(fout);
                               1201                 :            185 :     dumpStdStrings(fout);
 2749 tgl@sss.pgh.pa.us        1202                 :            185 :     dumpSearchPath(fout);
                               1203                 :                : 
                               1204                 :                :     /* The database items are always next, unless we don't want them at all */
 2781                          1205         [ +  + ]:            185 :     if (dopt.outputCreateDB)
 3524                          1206                 :             84 :         dumpDatabase(fout);
                               1207                 :                : 
                               1208                 :                :     /* Now the rearrangeable objects. */
 7945                          1209         [ +  + ]:         819380 :     for (i = 0; i < numObjs; i++)
 3524                          1210                 :         819195 :         dumpDumpableObject(fout, dobjs[i]);
                               1211                 :                : 
                               1212                 :                :     /*
                               1213                 :                :      * Set up options info to ensure we dump what we want.
                               1214                 :                :      */
 4848                          1215                 :            185 :     ropt = NewRestoreOptions();
                               1216                 :            185 :     ropt->filename = filename;
                               1217                 :                : 
                               1218                 :                :     /* if you change this list, see dumpOptionsFromRestoreOptions */
 1808                          1219         [ +  + ]:            185 :     ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
                               1220         [ +  + ]:            185 :     ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
                               1221         [ +  + ]:            185 :     ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
                               1222         [ +  + ]:            185 :     ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
                               1223                 :            185 :     ropt->cparams.promptPassword = dopt.cparams.promptPassword;
 3891                          1224                 :            185 :     ropt->dropSchema = dopt.outputClean;
  285 nathan@postgresql.or     1225                 :            185 :     ropt->dumpData = dopt.dumpData;
                               1226                 :            185 :     ropt->dumpSchema = dopt.dumpSchema;
  198 jdavis@postgresql.or     1227                 :            185 :     ropt->dumpStatistics = dopt.dumpStatistics;
 3891 tgl@sss.pgh.pa.us        1228                 :            185 :     ropt->if_exists = dopt.if_exists;
                               1229                 :            185 :     ropt->column_inserts = dopt.column_inserts;
                               1230                 :            185 :     ropt->dumpSections = dopt.dumpSections;
                               1231                 :            185 :     ropt->aclsSkip = dopt.aclsSkip;
                               1232                 :            185 :     ropt->superuser = dopt.outputSuperuser;
                               1233                 :            185 :     ropt->createDB = dopt.outputCreateDB;
                               1234                 :            185 :     ropt->noOwner = dopt.outputNoOwner;
 1328 michael@paquier.xyz      1235                 :            185 :     ropt->noTableAm = dopt.outputNoTableAm;
 3891 tgl@sss.pgh.pa.us        1236                 :            185 :     ropt->noTablespace = dopt.outputNoTablespaces;
                               1237                 :            185 :     ropt->disable_triggers = dopt.disable_triggers;
                               1238                 :            185 :     ropt->use_setsessauth = dopt.use_setsessauth;
                               1239                 :            185 :     ropt->disable_dollar_quoting = dopt.disable_dollar_quoting;
                               1240                 :            185 :     ropt->dump_inserts = dopt.dump_inserts;
 2781                          1241                 :            185 :     ropt->no_comments = dopt.no_comments;
  174                          1242                 :            185 :     ropt->no_policies = dopt.no_policies;
 3039 peter_e@gmx.net          1243                 :            185 :     ropt->no_publications = dopt.no_publications;
 3891 tgl@sss.pgh.pa.us        1244                 :            185 :     ropt->no_security_labels = dopt.no_security_labels;
 3042 peter_e@gmx.net          1245                 :            185 :     ropt->no_subscriptions = dopt.no_subscriptions;
 3891 tgl@sss.pgh.pa.us        1246                 :            185 :     ropt->lockWaitTimeout = dopt.lockWaitTimeout;
                               1247                 :            185 :     ropt->include_everything = dopt.include_everything;
                               1248                 :            185 :     ropt->enable_row_security = dopt.enable_row_security;
 3301 peter_e@gmx.net          1249                 :            185 :     ropt->sequence_data = dopt.sequence_data;
 3106 sfrost@snowman.net       1250                 :            185 :     ropt->binary_upgrade = dopt.binary_upgrade;
   26 nathan@postgresql.or     1251         [ +  + ]:            185 :     ropt->restrict_key = dopt.restrict_key ? pg_strdup(dopt.restrict_key) : NULL;
                               1252                 :                : 
 1009 michael@paquier.xyz      1253                 :            185 :     ropt->compression_spec = compression_spec;
                               1254                 :                : 
 4836 bruce@momjian.us         1255                 :            185 :     ropt->suppressDumpWarnings = true;   /* We've already shown them */
                               1256                 :                : 
 3524 tgl@sss.pgh.pa.us        1257                 :            185 :     SetArchiveOptions(fout, &dopt, ropt);
                               1258                 :                : 
                               1259                 :                :     /* Mark which entries should be output */
                               1260                 :            185 :     ProcessArchiveRestoreOptions(fout);
                               1261                 :                : 
                               1262                 :                :     /*
                               1263                 :                :      * The archive's TOC entries are now marked as to which ones will actually
                               1264                 :                :      * be output, so we can set up their dependency lists properly. This isn't
                               1265                 :                :      * necessary for plain-text output, though.
                               1266                 :                :      */
 4821                          1267         [ +  + ]:            185 :     if (!plainText)
                               1268                 :             55 :         BuildArchiveDependencies(fout);
                               1269                 :                : 
                               1270                 :                :     /*
                               1271                 :                :      * And finally we can do the actual output.
                               1272                 :                :      *
                               1273                 :                :      * Note: for non-plain-text output formats, the output file is written
                               1274                 :                :      * inside CloseArchive().  This is, um, bizarre; but not worth changing
                               1275                 :                :      * right now.
                               1276                 :                :      */
 4848                          1277         [ +  + ]:            185 :     if (plainText)
   38 andrew@dunslane.net      1278                 :            130 :         RestoreArchive(fout);
                               1279                 :                : 
 3524 tgl@sss.pgh.pa.us        1280                 :            184 :     CloseArchive(fout);
                               1281                 :                : 
 4951 rhaas@postgresql.org     1282                 :            184 :     exit_nicely(0);
                               1283                 :                : }
                               1284                 :                : 
                               1285                 :                : 
                               1286                 :                : static void
 8520 tgl@sss.pgh.pa.us        1287                 :              1 : help(const char *progname)
                               1288                 :                : {
   79 peter@eisentraut.org     1289                 :              1 :     printf(_("%s exports a PostgreSQL database as an SQL script or to other formats.\n\n"), progname);
 8410 peter_e@gmx.net          1290                 :              1 :     printf(_("Usage:\n"));
 8359                          1291                 :              1 :     printf(_("  %s [OPTION]... [DBNAME]\n"), progname);
                               1292                 :                : 
                               1293                 :              1 :     printf(_("\nGeneral options:\n"));
 4859                          1294                 :              1 :     printf(_("  -f, --file=FILENAME          output file or directory name\n"));
                               1295                 :              1 :     printf(_("  -F, --format=c|d|t|p         output file format (custom, directory, tar,\n"
                               1296                 :                :              "                               plain text (default))\n"));
 4549 andrew@dunslane.net      1297                 :              1 :     printf(_("  -j, --jobs=NUM               use this many parallel jobs to dump\n"));
 4859 peter_e@gmx.net          1298                 :              1 :     printf(_("  -v, --verbose                verbose mode\n"));
 4828                          1299                 :              1 :     printf(_("  -V, --version                output version information, then exit\n"));
  841 peter@eisentraut.org     1300                 :              1 :     printf(_("  -Z, --compress=METHOD[:DETAIL]\n"
                               1301                 :                :              "                               compress as specified\n"));
 4859 peter_e@gmx.net          1302                 :              1 :     printf(_("  --lock-wait-timeout=TIMEOUT  fail after waiting TIMEOUT for a table lock\n"));
 3090 andrew@dunslane.net      1303                 :              1 :     printf(_("  --no-sync                    do not wait for changes to be written safely to disk\n"));
  731 nathan@postgresql.or     1304                 :              1 :     printf(_("  --sync-method=METHOD         set method for syncing files to disk\n"));
 4828 peter_e@gmx.net          1305                 :              1 :     printf(_("  -?, --help                   show this help, then exit\n"));
                               1306                 :                : 
 8359                          1307                 :              1 :     printf(_("\nOptions controlling the output content:\n"));
  198 jdavis@postgresql.or     1308                 :              1 :     printf(_("  -a, --data-only              dump only the data, not the schema or statistics\n"));
  841 peter@eisentraut.org     1309                 :              1 :     printf(_("  -b, --large-objects          include large objects in dump\n"));
                               1310                 :              1 :     printf(_("  --blobs                      (same as --large-objects, deprecated)\n"));
                               1311                 :              1 :     printf(_("  -B, --no-large-objects       exclude large objects in dump\n"));
                               1312                 :              1 :     printf(_("  --no-blobs                   (same as --no-large-objects, deprecated)\n"));
 4859 peter_e@gmx.net          1313                 :              1 :     printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
                               1314                 :              1 :     printf(_("  -C, --create                 include commands to create database in dump\n"));
 1620 michael@paquier.xyz      1315                 :              1 :     printf(_("  -e, --extension=PATTERN      dump the specified extension(s) only\n"));
 4859 peter_e@gmx.net          1316                 :              1 :     printf(_("  -E, --encoding=ENCODING      dump the data in encoding ENCODING\n"));
 2195 peter@eisentraut.org     1317                 :              1 :     printf(_("  -n, --schema=PATTERN         dump the specified schema(s) only\n"));
                               1318                 :              1 :     printf(_("  -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
 4859 peter_e@gmx.net          1319                 :              1 :     printf(_("  -O, --no-owner               skip restoration of object ownership in\n"
                               1320                 :                :              "                               plain-text format\n"));
  198 jdavis@postgresql.or     1321                 :              1 :     printf(_("  -s, --schema-only            dump only the schema, no data or statistics\n"));
 4859 peter_e@gmx.net          1322                 :              1 :     printf(_("  -S, --superuser=NAME         superuser user name to use in plain-text format\n"));
  907 tgl@sss.pgh.pa.us        1323                 :              1 :     printf(_("  -t, --table=PATTERN          dump only the specified table(s)\n"));
 2195 peter@eisentraut.org     1324                 :              1 :     printf(_("  -T, --exclude-table=PATTERN  do NOT dump the specified table(s)\n"));
 4859 peter_e@gmx.net          1325                 :              1 :     printf(_("  -x, --no-privileges          do not dump privileges (grant/revoke)\n"));
                               1326                 :              1 :     printf(_("  --binary-upgrade             for use by upgrade utilities only\n"));
                               1327                 :              1 :     printf(_("  --column-inserts             dump data as INSERT commands with column names\n"));
                               1328                 :              1 :     printf(_("  --disable-dollar-quoting     disable dollar quoting, use SQL standard quoting\n"));
                               1329                 :              1 :     printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
 3643                          1330                 :              1 :     printf(_("  --enable-row-security        enable row security (dump only content user has\n"
                               1331                 :                :              "                               access to)\n"));
  500 peter@eisentraut.org     1332                 :              1 :     printf(_("  --exclude-extension=PATTERN  do NOT dump the specified extension(s)\n"));
  907 tgl@sss.pgh.pa.us        1333                 :              1 :     printf(_("  --exclude-table-and-children=PATTERN\n"
                               1334                 :                :              "                               do NOT dump the specified table(s), including\n"
                               1335                 :                :              "                               child and partition tables\n"));
 2195 peter@eisentraut.org     1336                 :              1 :     printf(_("  --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
  907 tgl@sss.pgh.pa.us        1337                 :              1 :     printf(_("  --exclude-table-data-and-children=PATTERN\n"
                               1338                 :                :              "                               do NOT dump data for the specified table(s),\n"
                               1339                 :                :              "                               including child and partition tables\n"));
 2392 andrew@dunslane.net      1340                 :              1 :     printf(_("  --extra-float-digits=NUM     override default setting for extra_float_digits\n"));
  647 dgustafsson@postgres     1341                 :              1 :     printf(_("  --filter=FILENAME            include or exclude objects and data from dump\n"
                               1342                 :                :              "                               based on expressions in FILENAME\n"));
 4205 alvherre@alvh.no-ip.     1343                 :              1 :     printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
 1991                          1344                 :              1 :     printf(_("  --include-foreign-data=PATTERN\n"
                               1345                 :                :              "                               include data of foreign tables on foreign\n"
                               1346                 :                :              "                               servers matching PATTERN\n"));
 4859 peter_e@gmx.net          1347                 :              1 :     printf(_("  --inserts                    dump data as INSERT commands, rather than COPY\n"));
 2651                          1348                 :              1 :     printf(_("  --load-via-partition-root    load partitions via the root table\n"));
  290 bruce@momjian.us         1349                 :              1 :     printf(_("  --no-comments                do not dump comment commands\n"));
  198 jdavis@postgresql.or     1350                 :              1 :     printf(_("  --no-data                    do not dump data\n"));
  174 tgl@sss.pgh.pa.us        1351                 :              1 :     printf(_("  --no-policies                do not dump row security policies\n"));
 3039 peter_e@gmx.net          1352                 :              1 :     printf(_("  --no-publications            do not dump publications\n"));
  198 jdavis@postgresql.or     1353                 :              1 :     printf(_("  --no-schema                  do not dump schema\n"));
 4859 peter_e@gmx.net          1354                 :              1 :     printf(_("  --no-security-labels         do not dump security label assignments\n"));
  198 jdavis@postgresql.or     1355                 :              1 :     printf(_("  --no-statistics              do not dump statistics\n"));
 3042 peter_e@gmx.net          1356                 :              1 :     printf(_("  --no-subscriptions           do not dump subscriptions\n"));
 1328 michael@paquier.xyz      1357                 :              1 :     printf(_("  --no-table-access-method     do not dump table access methods\n"));
 4859 peter_e@gmx.net          1358                 :              1 :     printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
 1576 peter@eisentraut.org     1359                 :              1 :     printf(_("  --no-toast-compression       do not dump TOAST compression methods\n"));
 4859 peter_e@gmx.net          1360                 :              1 :     printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
 2612 tmunro@postgresql.or     1361                 :              1 :     printf(_("  --on-conflict-do-nothing     add ON CONFLICT DO NOTHING to INSERT commands\n"));
 4859 peter_e@gmx.net          1362                 :              1 :     printf(_("  --quote-all-identifiers      quote all identifiers, even if not key words\n"));
   26 nathan@postgresql.or     1363                 :              1 :     printf(_("  --restrict-key=RESTRICT_KEY  use provided string as psql \\restrict key\n"));
 2375 alvherre@alvh.no-ip.     1364                 :              1 :     printf(_("  --rows-per-insert=NROWS      number of rows per INSERT; implies --inserts\n"));
 4859 peter_e@gmx.net          1365                 :              1 :     printf(_("  --section=SECTION            dump named section (pre-data, data, or post-data)\n"));
  165 nathan@postgresql.or     1366                 :              1 :     printf(_("  --sequence-data              include sequence data in dump\n"));
 4859 peter_e@gmx.net          1367                 :              1 :     printf(_("  --serializable-deferrable    wait until the dump can run without anomalies\n"));
 3632                          1368                 :              1 :     printf(_("  --snapshot=SNAPSHOT          use given snapshot for the dump\n"));
   35 jdavis@postgresql.or     1369                 :              1 :     printf(_("  --statistics                 dump the statistics\n"));
  198                          1370                 :              1 :     printf(_("  --statistics-only            dump only the statistics, not schema or data\n"));
 3645 teodor@sigaev.ru         1371                 :              1 :     printf(_("  --strict-names               require table and/or schema include patterns to\n"
                               1372                 :                :              "                               match at least one entity each\n"));
  841 peter@eisentraut.org     1373                 :              1 :     printf(_("  --table-and-children=PATTERN dump only the specified table(s), including\n"
                               1374                 :                :              "                               child and partition tables\n"));
 6909 peter_e@gmx.net          1375                 :              1 :     printf(_("  --use-set-session-authorization\n"
                               1376                 :                :              "                               use SET SESSION AUTHORIZATION commands instead of\n"
                               1377                 :                :              "                               ALTER OWNER commands to set ownership\n"));
                               1378                 :                : 
 8359                          1379                 :              1 :     printf(_("\nConnection options:\n"));
 4576 heikki.linnakangas@i     1380                 :              1 :     printf(_("  -d, --dbname=DBNAME      database to dump\n"));
 8123 bruce@momjian.us         1381                 :              1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
 8359 peter_e@gmx.net          1382                 :              1 :     printf(_("  -p, --port=PORT          database server port number\n"));
                               1383                 :              1 :     printf(_("  -U, --username=NAME      connect as specified database user\n"));
 6017                          1384                 :              1 :     printf(_("  -w, --no-password        never prompt for password\n"));
 8359                          1385                 :              1 :     printf(_("  -W, --password           force password prompt (should happen automatically)\n"));
 5218                          1386                 :              1 :     printf(_("  --role=ROLENAME          do SET ROLE before dump\n"));
                               1387                 :                : 
 8081                          1388                 :              1 :     printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
                               1389                 :                :              "variable value is used.\n\n"));
 2017 peter@eisentraut.org     1390                 :              1 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
                               1391                 :              1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 8520 tgl@sss.pgh.pa.us        1392                 :              1 : }
                               1393                 :                : 
                               1394                 :                : static void
 3524                          1395                 :            220 : setup_connection(Archive *AH, const char *dumpencoding,
                               1396                 :                :                  const char *dumpsnapshot, char *use_role)
                               1397                 :                : {
                               1398                 :            220 :     DumpOptions *dopt = AH->dopt;
 4951 rhaas@postgresql.org     1399                 :            220 :     PGconn     *conn = GetConnection(AH);
                               1400                 :                :     const char *std_strings;
                               1401                 :                : 
 2749 noah@leadboat.com        1402                 :            220 :     PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL));
                               1403                 :                : 
                               1404                 :                :     /*
                               1405                 :                :      * Set the client encoding if requested.
                               1406                 :                :      */
 4971 rhaas@postgresql.org     1407         [ +  + ]:            220 :     if (dumpencoding)
                               1408                 :                :     {
 4951                          1409         [ -  + ]:             20 :         if (PQsetClientEncoding(conn, dumpencoding) < 0)
 1247 tgl@sss.pgh.pa.us        1410                 :UBC           0 :             pg_fatal("invalid client encoding \"%s\" specified",
                               1411                 :                :                      dumpencoding);
                               1412                 :                :     }
                               1413                 :                : 
                               1414                 :                :     /*
                               1415                 :                :      * Get the active encoding and the standard_conforming_strings setting, so
                               1416                 :                :      * we know how to escape strings.
                               1417                 :                :      */
 4951 rhaas@postgresql.org     1418                 :CBC         220 :     AH->encoding = PQclientEncoding(conn);
  208 andres@anarazel.de       1419                 :            220 :     setFmtEncoding(AH->encoding);
                               1420                 :                : 
 4951 rhaas@postgresql.org     1421                 :            220 :     std_strings = PQparameterStatus(conn, "standard_conforming_strings");
 4971                          1422   [ +  -  +  - ]:            220 :     AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
                               1423                 :                : 
                               1424                 :                :     /*
                               1425                 :                :      * Set the role if requested.  In a parallel dump worker, we'll be passed
                               1426                 :                :      * use_role == NULL, but AH->use_role is already set (if user specified it
                               1427                 :                :      * originally) and we should use that.
                               1428                 :                :      */
 4549 andrew@dunslane.net      1429   [ +  +  +  + ]:            220 :     if (!use_role && AH->use_role)
                               1430                 :              2 :         use_role = AH->use_role;
                               1431                 :                : 
                               1432                 :                :     /* Set the role if requested */
 1362 tgl@sss.pgh.pa.us        1433         [ +  + ]:            220 :     if (use_role)
                               1434                 :                :     {
 4971 rhaas@postgresql.org     1435                 :              5 :         PQExpBuffer query = createPQExpBuffer();
                               1436                 :                : 
                               1437                 :              5 :         appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
 4960                          1438                 :              5 :         ExecuteSqlStatement(AH, query->data);
 4971                          1439                 :              5 :         destroyPQExpBuffer(query);
                               1440                 :                : 
                               1441                 :                :         /* save it for possible later use by parallel workers */
 4549 andrew@dunslane.net      1442         [ +  + ]:              5 :         if (!AH->use_role)
 3384 tgl@sss.pgh.pa.us        1443                 :              3 :             AH->use_role = pg_strdup(use_role);
                               1444                 :                :     }
                               1445                 :                : 
                               1446                 :                :     /* Set the datestyle to ISO to ensure the dump's portability */
 4960 rhaas@postgresql.org     1447                 :            220 :     ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
                               1448                 :                : 
                               1449                 :                :     /* Likewise, avoid using sql_standard intervalstyle */
 1362 tgl@sss.pgh.pa.us        1450                 :            220 :     ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
                               1451                 :                : 
                               1452                 :                :     /*
                               1453                 :                :      * Use an explicitly specified extra_float_digits if it has been provided.
                               1454                 :                :      * Otherwise, set extra_float_digits so that we can dump float data
                               1455                 :                :      * exactly (given correctly implemented float I/O code, anyway).
                               1456                 :                :      */
 2392 andrew@dunslane.net      1457         [ -  + ]:            220 :     if (have_extra_float_digits)
                               1458                 :                :     {
 2392 andrew@dunslane.net      1459                 :UBC           0 :         PQExpBuffer q = createPQExpBuffer();
                               1460                 :                : 
                               1461                 :              0 :         appendPQExpBuffer(q, "SET extra_float_digits TO %d",
                               1462                 :                :                           extra_float_digits);
                               1463                 :              0 :         ExecuteSqlStatement(AH, q->data);
                               1464                 :              0 :         destroyPQExpBuffer(q);
                               1465                 :                :     }
                               1466                 :                :     else
 1362 tgl@sss.pgh.pa.us        1467                 :CBC         220 :         ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
                               1468                 :                : 
                               1469                 :                :     /*
                               1470                 :                :      * Disable synchronized scanning, to prevent unpredictable changes in row
                               1471                 :                :      * ordering across a dump and reload.
                               1472                 :                :      */
                               1473                 :            220 :     ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
                               1474                 :                : 
                               1475                 :                :     /*
                               1476                 :                :      * Disable timeouts if supported.
                               1477                 :                :      */
 3251                          1478                 :            220 :     ExecuteSqlStatement(AH, "SET statement_timeout = 0");
 4557                          1479         [ +  - ]:            220 :     if (AH->remoteVersion >= 90300)
                               1480                 :            220 :         ExecuteSqlStatement(AH, "SET lock_timeout = 0");
 3370                          1481         [ +  - ]:            220 :     if (AH->remoteVersion >= 90600)
                               1482                 :            220 :         ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
  569 akorotkov@postgresql     1483         [ +  - ]:            220 :     if (AH->remoteVersion >= 170000)
                               1484                 :            220 :         ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
                               1485                 :                : 
                               1486                 :                :     /*
                               1487                 :                :      * Quote all identifiers, if requested.
                               1488                 :                :      */
 1362 tgl@sss.pgh.pa.us        1489         [ +  + ]:            220 :     if (quote_all_identifiers)
 4960 rhaas@postgresql.org     1490                 :             34 :         ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
                               1491                 :                : 
                               1492                 :                :     /*
                               1493                 :                :      * Adjust row-security mode, if supported.
                               1494                 :                :      */
 3853 tgl@sss.pgh.pa.us        1495         [ +  - ]:            220 :     if (AH->remoteVersion >= 90500)
                               1496                 :                :     {
                               1497         [ -  + ]:            220 :         if (dopt->enable_row_security)
 3853 tgl@sss.pgh.pa.us        1498                 :UBC           0 :             ExecuteSqlStatement(AH, "SET row_security = on");
                               1499                 :                :         else
 3853 tgl@sss.pgh.pa.us        1500                 :CBC         220 :             ExecuteSqlStatement(AH, "SET row_security = off");
                               1501                 :                :     }
                               1502                 :                : 
                               1503                 :                :     /*
                               1504                 :                :      * For security reasons, we restrict the expansion of non-system views and
                               1505                 :                :      * access to foreign tables during the pg_dump process. This restriction
                               1506                 :                :      * is adjusted when dumping foreign table data.
                               1507                 :                :      */
  397 msawada@postgresql.o     1508                 :            220 :     set_restrict_relation_kind(AH, "view, foreign-table");
                               1509                 :                : 
                               1510                 :                :     /*
                               1511                 :                :      * Initialize prepared-query state to "nothing prepared".  We do this here
                               1512                 :                :      * so that a parallel dump worker will have its own state.
                               1513                 :                :      */
 1370 tgl@sss.pgh.pa.us        1514                 :            220 :     AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
                               1515                 :                : 
                               1516                 :                :     /*
                               1517                 :                :      * Start transaction-snapshot mode transaction to dump consistent data.
                               1518                 :                :      */
 4549 andrew@dunslane.net      1519                 :            220 :     ExecuteSqlStatement(AH, "BEGIN");
                               1520                 :                : 
                               1521                 :                :     /*
                               1522                 :                :      * To support the combination of serializable_deferrable with the jobs
                               1523                 :                :      * option we use REPEATABLE READ for the worker connections that are
                               1524                 :                :      * passed a snapshot.  As long as the snapshot is acquired in a
                               1525                 :                :      * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
                               1526                 :                :      * REPEATABLE READ transaction provides the appropriate integrity
                               1527                 :                :      * guarantees.  This is a kluge, but safe for back-patching.
                               1528                 :                :      */
 1362 tgl@sss.pgh.pa.us        1529   [ -  +  -  - ]:            220 :     if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
 1362 tgl@sss.pgh.pa.us        1530                 :UBC           0 :         ExecuteSqlStatement(AH,
                               1531                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1532                 :                :                             "SERIALIZABLE, READ ONLY, DEFERRABLE");
                               1533                 :                :     else
 4549 andrew@dunslane.net      1534                 :CBC         220 :         ExecuteSqlStatement(AH,
                               1535                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1536                 :                :                             "REPEATABLE READ, READ ONLY");
                               1537                 :                : 
                               1538                 :                :     /*
                               1539                 :                :      * If user specified a snapshot to use, select that.  In a parallel dump
                               1540                 :                :      * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
                               1541                 :                :      * is already set (if the server can handle it) and we should use that.
                               1542                 :                :      */
 3946 simon@2ndQuadrant.co     1543         [ -  + ]:            220 :     if (dumpsnapshot)
 3384 tgl@sss.pgh.pa.us        1544                 :UBC           0 :         AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
                               1545                 :                : 
 3946 simon@2ndQuadrant.co     1546         [ +  + ]:CBC         220 :     if (AH->sync_snapshot_id)
                               1547                 :                :     {
                               1548                 :             18 :         PQExpBuffer query = createPQExpBuffer();
                               1549                 :                : 
 2256 drowley@postgresql.o     1550                 :             18 :         appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
 3946 simon@2ndQuadrant.co     1551                 :             18 :         appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
                               1552                 :             18 :         ExecuteSqlStatement(AH, query->data);
                               1553                 :             18 :         destroyPQExpBuffer(query);
                               1554                 :                :     }
 1361 tgl@sss.pgh.pa.us        1555         [ +  + ]:            202 :     else if (AH->numWorkers > 1)
                               1556                 :                :     {
 2943 peter_e@gmx.net          1557   [ -  +  -  - ]:              9 :         if (AH->isStandby && AH->remoteVersion < 100000)
 1247 tgl@sss.pgh.pa.us        1558                 :UBC           0 :             pg_fatal("parallel dumps from standby servers are not supported by this server version");
 3946 simon@2ndQuadrant.co     1559                 :CBC           9 :         AH->sync_snapshot_id = get_synchronized_snapshot(AH);
                               1560                 :                :     }
 4549 andrew@dunslane.net      1561                 :            220 : }
                               1562                 :                : 
                               1563                 :                : /* Set up connection for a parallel worker process */
                               1564                 :                : static void
 3384 tgl@sss.pgh.pa.us        1565                 :             18 : setupDumpWorker(Archive *AH)
                               1566                 :                : {
                               1567                 :                :     /*
                               1568                 :                :      * We want to re-select all the same values the leader connection is
                               1569                 :                :      * using.  We'll have inherited directly-usable values in
                               1570                 :                :      * AH->sync_snapshot_id and AH->use_role, but we need to translate the
                               1571                 :                :      * inherited encoding value back to a string to pass to setup_connection.
                               1572                 :                :      */
                               1573                 :             18 :     setup_connection(AH,
                               1574                 :                :                      pg_encoding_to_char(AH->encoding),
                               1575                 :                :                      NULL,
                               1576                 :                :                      NULL);
 4549 andrew@dunslane.net      1577                 :             18 : }
                               1578                 :                : 
                               1579                 :                : static char *
                               1580                 :              9 : get_synchronized_snapshot(Archive *fout)
                               1581                 :                : {
 3384 tgl@sss.pgh.pa.us        1582                 :              9 :     char       *query = "SELECT pg_catalog.pg_export_snapshot()";
                               1583                 :                :     char       *result;
                               1584                 :                :     PGresult   *res;
                               1585                 :                : 
 4549 andrew@dunslane.net      1586                 :              9 :     res = ExecuteSqlQueryForSingleRow(fout, query);
 3384 tgl@sss.pgh.pa.us        1587                 :              9 :     result = pg_strdup(PQgetvalue(res, 0, 0));
 4549 andrew@dunslane.net      1588                 :              9 :     PQclear(res);
                               1589                 :                : 
                               1590                 :              9 :     return result;
                               1591                 :                : }
                               1592                 :                : 
                               1593                 :                : static ArchiveFormat
 5340 heikki.linnakangas@i     1594                 :            211 : parseArchiveFormat(const char *format, ArchiveMode *mode)
                               1595                 :                : {
                               1596                 :                :     ArchiveFormat archiveFormat;
                               1597                 :                : 
                               1598                 :            211 :     *mode = archModeWrite;
                               1599                 :                : 
                               1600   [ +  +  -  + ]:            211 :     if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
                               1601                 :                :     {
                               1602                 :                :         /* This is used by pg_dumpall, and is not documented */
                               1603                 :             43 :         archiveFormat = archNull;
                               1604                 :             43 :         *mode = archModeAppend;
                               1605                 :                :     }
                               1606         [ -  + ]:            168 :     else if (pg_strcasecmp(format, "c") == 0)
 5340 heikki.linnakangas@i     1607                 :UBC           0 :         archiveFormat = archCustom;
 5340 heikki.linnakangas@i     1608         [ +  + ]:CBC         168 :     else if (pg_strcasecmp(format, "custom") == 0)
                               1609                 :             42 :         archiveFormat = archCustom;
                               1610         [ -  + ]:            126 :     else if (pg_strcasecmp(format, "d") == 0)
 5340 heikki.linnakangas@i     1611                 :UBC           0 :         archiveFormat = archDirectory;
 5340 heikki.linnakangas@i     1612         [ +  + ]:CBC         126 :     else if (pg_strcasecmp(format, "directory") == 0)
                               1613                 :             11 :         archiveFormat = archDirectory;
                               1614         [ +  + ]:            115 :     else if (pg_strcasecmp(format, "p") == 0)
                               1615                 :            107 :         archiveFormat = archNull;
                               1616         [ +  + ]:              8 :     else if (pg_strcasecmp(format, "plain") == 0)
                               1617                 :              4 :         archiveFormat = archNull;
                               1618         [ -  + ]:              4 :     else if (pg_strcasecmp(format, "t") == 0)
 5340 heikki.linnakangas@i     1619                 :UBC           0 :         archiveFormat = archTar;
 5340 heikki.linnakangas@i     1620         [ +  + ]:CBC           4 :     else if (pg_strcasecmp(format, "tar") == 0)
                               1621                 :              3 :         archiveFormat = archTar;
                               1622                 :                :     else
 1247 tgl@sss.pgh.pa.us        1623                 :              1 :         pg_fatal("invalid output format \"%s\" specified", format);
 5340 heikki.linnakangas@i     1624                 :            210 :     return archiveFormat;
                               1625                 :                : }
                               1626                 :                : 
                               1627                 :                : /*
                               1628                 :                :  * Find the OIDs of all schemas matching the given list of patterns,
                               1629                 :                :  * and append them to the given OID list.
                               1630                 :                :  */
                               1631                 :                : static void
 4961 rhaas@postgresql.org     1632                 :            213 : expand_schema_name_patterns(Archive *fout,
                               1633                 :                :                             SimpleStringList *patterns,
                               1634                 :                :                             SimpleOidList *oids,
                               1635                 :                :                             bool strict_names)
                               1636                 :                : {
                               1637                 :                :     PQExpBuffer query;
                               1638                 :                :     PGresult   *res;
                               1639                 :                :     SimpleStringListCell *cell;
                               1640                 :                :     int         i;
                               1641                 :                : 
 6907 tgl@sss.pgh.pa.us        1642         [ +  + ]:            213 :     if (patterns->head == NULL)
                               1643                 :            192 :         return;                 /* nothing to do */
                               1644                 :                : 
                               1645                 :             21 :     query = createPQExpBuffer();
                               1646                 :                : 
                               1647                 :                :     /*
                               1648                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1649                 :                :      * duplicate entries in the OID list, but we don't care.
                               1650                 :                :      */
                               1651                 :                : 
                               1652         [ +  + ]:             36 :     for (cell = patterns->head; cell; cell = cell->next)
                               1653                 :                :     {
                               1654                 :                :         PQExpBufferData dbbuf;
                               1655                 :                :         int         dotcnt;
                               1656                 :                : 
 2256 drowley@postgresql.o     1657                 :             21 :         appendPQExpBufferStr(query,
                               1658                 :                :                              "SELECT oid FROM pg_catalog.pg_namespace n\n");
 1235 rhaas@postgresql.org     1659                 :             21 :         initPQExpBuffer(&dbbuf);
 4951                          1660                 :             21 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1661                 :                :                               false, NULL, "n.nspname", NULL, NULL, &dbbuf,
                               1662                 :                :                               &dotcnt);
 1235                          1663         [ +  + ]:             21 :         if (dotcnt > 1)
                               1664                 :              2 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1665                 :                :                      cell->val);
                               1666         [ +  + ]:             19 :         else if (dotcnt == 1)
                               1667                 :              3 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1668                 :             16 :         termPQExpBuffer(&dbbuf);
                               1669                 :                : 
 3645 teodor@sigaev.ru         1670                 :             16 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1671   [ +  +  +  - ]:             16 :         if (strict_names && PQntuples(res) == 0)
 1247 tgl@sss.pgh.pa.us        1672                 :              1 :             pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
                               1673                 :                : 
 3645 teodor@sigaev.ru         1674         [ +  + ]:             29 :         for (i = 0; i < PQntuples(res); i++)
                               1675                 :                :         {
                               1676                 :             14 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1677                 :                :         }
                               1678                 :                : 
                               1679                 :             15 :         PQclear(res);
                               1680                 :             15 :         resetPQExpBuffer(query);
                               1681                 :                :     }
                               1682                 :                : 
 6907 tgl@sss.pgh.pa.us        1683                 :             15 :     destroyPQExpBuffer(query);
                               1684                 :                : }
                               1685                 :                : 
                               1686                 :                : /*
                               1687                 :                :  * Find the OIDs of all extensions matching the given list of patterns,
                               1688                 :                :  * and append them to the given OID list.
                               1689                 :                :  */
                               1690                 :                : static void
 1620 michael@paquier.xyz      1691                 :            191 : expand_extension_name_patterns(Archive *fout,
                               1692                 :                :                                SimpleStringList *patterns,
                               1693                 :                :                                SimpleOidList *oids,
                               1694                 :                :                                bool strict_names)
                               1695                 :                : {
                               1696                 :                :     PQExpBuffer query;
                               1697                 :                :     PGresult   *res;
                               1698                 :                :     SimpleStringListCell *cell;
                               1699                 :                :     int         i;
                               1700                 :                : 
                               1701         [ +  + ]:            191 :     if (patterns->head == NULL)
                               1702                 :            184 :         return;                 /* nothing to do */
                               1703                 :                : 
                               1704                 :              7 :     query = createPQExpBuffer();
                               1705                 :                : 
                               1706                 :                :     /*
                               1707                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1708                 :                :      * duplicate entries in the OID list, but we don't care.
                               1709                 :                :      */
                               1710         [ +  + ]:             14 :     for (cell = patterns->head; cell; cell = cell->next)
                               1711                 :                :     {
                               1712                 :                :         int         dotcnt;
                               1713                 :                : 
                               1714                 :              7 :         appendPQExpBufferStr(query,
                               1715                 :                :                              "SELECT oid FROM pg_catalog.pg_extension e\n");
                               1716                 :              7 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1717                 :                :                               false, NULL, "e.extname", NULL, NULL, NULL,
                               1718                 :                :                               &dotcnt);
 1235 rhaas@postgresql.org     1719         [ -  + ]:              7 :         if (dotcnt > 0)
 1235 rhaas@postgresql.org     1720                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1721                 :                :                      cell->val);
                               1722                 :                : 
 1620 michael@paquier.xyz      1723                 :CBC           7 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1724   [ -  +  -  - ]:              7 :         if (strict_names && PQntuples(res) == 0)
 1247 tgl@sss.pgh.pa.us        1725                 :UBC           0 :             pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
                               1726                 :                : 
 1620 michael@paquier.xyz      1727         [ +  + ]:CBC          13 :         for (i = 0; i < PQntuples(res); i++)
                               1728                 :                :         {
                               1729                 :              6 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1730                 :                :         }
                               1731                 :                : 
                               1732                 :              7 :         PQclear(res);
                               1733                 :              7 :         resetPQExpBuffer(query);
                               1734                 :                :     }
                               1735                 :                : 
                               1736                 :              7 :     destroyPQExpBuffer(query);
                               1737                 :                : }
                               1738                 :                : 
                               1739                 :                : /*
                               1740                 :                :  * Find the OIDs of all foreign servers matching the given list of patterns,
                               1741                 :                :  * and append them to the given OID list.
                               1742                 :                :  */
                               1743                 :                : static void
 1991 alvherre@alvh.no-ip.     1744                 :            188 : expand_foreign_server_name_patterns(Archive *fout,
                               1745                 :                :                                     SimpleStringList *patterns,
                               1746                 :                :                                     SimpleOidList *oids)
                               1747                 :                : {
                               1748                 :                :     PQExpBuffer query;
                               1749                 :                :     PGresult   *res;
                               1750                 :                :     SimpleStringListCell *cell;
                               1751                 :                :     int         i;
                               1752                 :                : 
                               1753         [ +  + ]:            188 :     if (patterns->head == NULL)
                               1754                 :            185 :         return;                 /* nothing to do */
                               1755                 :                : 
                               1756                 :              3 :     query = createPQExpBuffer();
                               1757                 :                : 
                               1758                 :                :     /*
                               1759                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1760                 :                :      * duplicate entries in the OID list, but we don't care.
                               1761                 :                :      */
                               1762                 :                : 
                               1763         [ +  + ]:              5 :     for (cell = patterns->head; cell; cell = cell->next)
                               1764                 :                :     {
                               1765                 :                :         int         dotcnt;
                               1766                 :                : 
 1787 drowley@postgresql.o     1767                 :              3 :         appendPQExpBufferStr(query,
                               1768                 :                :                              "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
 1991 alvherre@alvh.no-ip.     1769                 :              3 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1770                 :                :                               false, NULL, "s.srvname", NULL, NULL, NULL,
                               1771                 :                :                               &dotcnt);
 1235 rhaas@postgresql.org     1772         [ -  + ]:              3 :         if (dotcnt > 0)
 1235 rhaas@postgresql.org     1773                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1774                 :                :                      cell->val);
                               1775                 :                : 
 1991 alvherre@alvh.no-ip.     1776                 :CBC           3 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1777         [ +  + ]:              3 :         if (PQntuples(res) == 0)
 1247 tgl@sss.pgh.pa.us        1778                 :              1 :             pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
                               1779                 :                : 
 1991 alvherre@alvh.no-ip.     1780         [ +  + ]:              4 :         for (i = 0; i < PQntuples(res); i++)
                               1781                 :              2 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1782                 :                : 
                               1783                 :              2 :         PQclear(res);
                               1784                 :              2 :         resetPQExpBuffer(query);
                               1785                 :                :     }
                               1786                 :                : 
                               1787                 :              2 :     destroyPQExpBuffer(query);
                               1788                 :                : }
                               1789                 :                : 
                               1790                 :                : /*
                               1791                 :                :  * Find the OIDs of all tables matching the given list of patterns,
                               1792                 :                :  * and append them to the given OID list. See also expand_dbname_patterns()
                               1793                 :                :  * in pg_dumpall.c
                               1794                 :                :  */
                               1795                 :                : static void
 4960 rhaas@postgresql.org     1796                 :           1137 : expand_table_name_patterns(Archive *fout,
                               1797                 :                :                            SimpleStringList *patterns, SimpleOidList *oids,
                               1798                 :                :                            bool strict_names, bool with_child_tables)
                               1799                 :                : {
                               1800                 :                :     PQExpBuffer query;
                               1801                 :                :     PGresult   *res;
                               1802                 :                :     SimpleStringListCell *cell;
                               1803                 :                :     int         i;
                               1804                 :                : 
 6907 tgl@sss.pgh.pa.us        1805         [ +  + ]:           1137 :     if (patterns->head == NULL)
                               1806                 :           1108 :         return;                 /* nothing to do */
                               1807                 :                : 
                               1808                 :             29 :     query = createPQExpBuffer();
                               1809                 :                : 
                               1810                 :                :     /*
                               1811                 :                :      * this might sometimes result in duplicate entries in the OID list, but
                               1812                 :                :      * we don't care.
                               1813                 :                :      */
                               1814                 :                : 
                               1815         [ +  + ]:             59 :     for (cell = patterns->head; cell; cell = cell->next)
                               1816                 :                :     {
                               1817                 :                :         PQExpBufferData dbbuf;
                               1818                 :                :         int         dotcnt;
                               1819                 :                : 
                               1820                 :                :         /*
                               1821                 :                :          * Query must remain ABSOLUTELY devoid of unqualified names.  This
                               1822                 :                :          * would be unnecessary given a pg_table_is_visible() variant taking a
                               1823                 :                :          * search_path argument.
                               1824                 :                :          *
                               1825                 :                :          * For with_child_tables, we start with the basic query's results and
                               1826                 :                :          * recursively search the inheritance tree to add child tables.
                               1827                 :                :          */
  907                          1828         [ +  + ]:             35 :         if (with_child_tables)
                               1829                 :                :         {
  141 drowley@postgresql.o     1830                 :              6 :             appendPQExpBufferStr(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
                               1831                 :                :         }
                               1832                 :                : 
 6907 tgl@sss.pgh.pa.us        1833                 :             35 :         appendPQExpBuffer(query,
                               1834                 :                :                           "SELECT c.oid"
                               1835                 :                :                           "\nFROM pg_catalog.pg_class c"
                               1836                 :                :                           "\n     LEFT JOIN pg_catalog.pg_namespace n"
                               1837                 :                :                           "\n     ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
                               1838                 :                :                           "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
                               1839                 :                :                           "\n    (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
                               1840                 :                :                           RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
                               1841                 :                :                           RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
                               1842                 :                :                           RELKIND_PARTITIONED_TABLE);
 1235 rhaas@postgresql.org     1843                 :             35 :         initPQExpBuffer(&dbbuf);
 4951                          1844                 :             35 :         processSQLNamePattern(GetConnection(fout), query, cell->val, true,
                               1845                 :                :                               false, "n.nspname", "c.relname", NULL,
                               1846                 :                :                               "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
                               1847                 :                :                               &dotcnt);
 1235                          1848         [ +  + ]:             35 :         if (dotcnt > 2)
                               1849                 :              1 :             pg_fatal("improper relation name (too many dotted names): %s",
                               1850                 :                :                      cell->val);
                               1851         [ +  + ]:             34 :         else if (dotcnt == 2)
                               1852                 :              2 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1853                 :             32 :         termPQExpBuffer(&dbbuf);
                               1854                 :                : 
  907 tgl@sss.pgh.pa.us        1855         [ +  + ]:             32 :         if (with_child_tables)
                               1856                 :                :         {
  141 drowley@postgresql.o     1857                 :              6 :             appendPQExpBufferStr(query, "UNION"
                               1858                 :                :                                  "\nSELECT i.inhrelid"
                               1859                 :                :                                  "\nFROM partition_tree p"
                               1860                 :                :                                  "\n     JOIN pg_catalog.pg_inherits i"
                               1861                 :                :                                  "\n     ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
                               1862                 :                :                                  "\n)"
                               1863                 :                :                                  "\nSELECT relid FROM partition_tree");
                               1864                 :                :         }
                               1865                 :                : 
 2749 noah@leadboat.com        1866                 :             32 :         ExecuteSqlStatement(fout, "RESET search_path");
 3645 teodor@sigaev.ru         1867                 :             32 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 2749 noah@leadboat.com        1868                 :             32 :         PQclear(ExecuteSqlQueryForSingleRow(fout,
                               1869                 :                :                                             ALWAYS_SECURE_SEARCH_PATH_SQL));
 3645 teodor@sigaev.ru         1870   [ +  +  +  + ]:             32 :         if (strict_names && PQntuples(res) == 0)
 1247 tgl@sss.pgh.pa.us        1871                 :              2 :             pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
                               1872                 :                : 
 3645 teodor@sigaev.ru         1873         [ +  + ]:             74 :         for (i = 0; i < PQntuples(res); i++)
                               1874                 :                :         {
                               1875                 :             44 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1876                 :                :         }
                               1877                 :                : 
                               1878                 :             30 :         PQclear(res);
                               1879                 :             30 :         resetPQExpBuffer(query);
                               1880                 :                :     }
                               1881                 :                : 
 6907 tgl@sss.pgh.pa.us        1882                 :             24 :     destroyPQExpBuffer(query);
                               1883                 :                : }
                               1884                 :                : 
                               1885                 :                : /*
                               1886                 :                :  * Verifies that the connected database name matches the given database name,
                               1887                 :                :  * and if not, dies with an error about the given pattern.
                               1888                 :                :  *
                               1889                 :                :  * The 'dbname' argument should be a literal name parsed from 'pattern'.
                               1890                 :                :  */
                               1891                 :                : static void
 1235 rhaas@postgresql.org     1892                 :              5 : prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
                               1893                 :                : {
                               1894                 :                :     const char *db;
                               1895                 :                : 
                               1896                 :              5 :     db = PQdb(conn);
                               1897         [ -  + ]:              5 :     if (db == NULL)
 1235 rhaas@postgresql.org     1898                 :UBC           0 :         pg_fatal("You are currently not connected to a database.");
                               1899                 :                : 
 1235 rhaas@postgresql.org     1900         [ +  - ]:CBC           5 :     if (strcmp(db, dbname) != 0)
                               1901                 :              5 :         pg_fatal("cross-database references are not implemented: %s",
                               1902                 :                :                  pattern);
 1235 rhaas@postgresql.org     1903                 :UBC           0 : }
                               1904                 :                : 
                               1905                 :                : /*
                               1906                 :                :  * checkExtensionMembership
                               1907                 :                :  *      Determine whether object is an extension member, and if so,
                               1908                 :                :  *      record an appropriate dependency and set the object's dump flag.
                               1909                 :                :  *
                               1910                 :                :  * It's important to call this for each object that could be an extension
                               1911                 :                :  * member.  Generally, we integrate this with determining the object's
                               1912                 :                :  * to-be-dumped-ness, since extension membership overrides other rules for that.
                               1913                 :                :  *
                               1914                 :                :  * Returns true if object is an extension member, else false.
                               1915                 :                :  */
                               1916                 :                : static bool
 3440 sfrost@snowman.net       1917                 :CBC      714407 : checkExtensionMembership(DumpableObject *dobj, Archive *fout)
                               1918                 :                : {
 3524 tgl@sss.pgh.pa.us        1919                 :         714407 :     ExtensionInfo *ext = findOwningExtension(dobj->catId);
                               1920                 :                : 
                               1921         [ +  + ]:         714407 :     if (ext == NULL)
                               1922                 :         713614 :         return false;
                               1923                 :                : 
                               1924                 :            793 :     dobj->ext_member = true;
                               1925                 :                : 
                               1926                 :                :     /* Record dependency so that getDependencies needn't deal with that */
                               1927                 :            793 :     addObjectDependency(dobj, ext->dobj.dumpId);
                               1928                 :                : 
                               1929                 :                :     /*
                               1930                 :                :      * In 9.6 and above, mark the member object to have any non-initial ACLs
                               1931                 :                :      * dumped.  (Any initial ACLs will be removed later, using data from
                               1932                 :                :      * pg_init_privs, so that we'll dump only the delta from the extension's
                               1933                 :                :      * initial setup.)
                               1934                 :                :      *
                               1935                 :                :      * Prior to 9.6, we do not include any extension member components.
                               1936                 :                :      *
                               1937                 :                :      * In binary upgrades, we still dump all components of the members
                               1938                 :                :      * individually, since the idea is to exactly reproduce the database
                               1939                 :                :      * contents rather than replace the extension contents with something
                               1940                 :                :      * different.
                               1941                 :                :      *
                               1942                 :                :      * Note: it might be interesting someday to implement storage and delta
                               1943                 :                :      * dumping of extension members' RLS policies and/or security labels.
                               1944                 :                :      * However there is a pitfall for RLS policies: trying to dump them
                               1945                 :                :      * requires getting a lock on their tables, and the calling user might not
                               1946                 :                :      * have privileges for that.  We need no lock to examine a table's ACLs,
                               1947                 :                :      * so the current feature doesn't have a problem of that sort.
                               1948                 :                :      */
 3410 sfrost@snowman.net       1949         [ +  + ]:            793 :     if (fout->dopt->binary_upgrade)
 3524 tgl@sss.pgh.pa.us        1950                 :            164 :         dobj->dump = ext->dobj.dump;
                               1951                 :                :     else
                               1952                 :                :     {
 3410 sfrost@snowman.net       1953         [ -  + ]:            629 :         if (fout->remoteVersion < 90600)
 3410 sfrost@snowman.net       1954                 :UBC           0 :             dobj->dump = DUMP_COMPONENT_NONE;
                               1955                 :                :         else
  663 tgl@sss.pgh.pa.us        1956                 :CBC         629 :             dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
                               1957                 :                :     }
                               1958                 :                : 
 3524                          1959                 :            793 :     return true;
                               1960                 :                : }
                               1961                 :                : 
                               1962                 :                : /*
                               1963                 :                :  * selectDumpableNamespace: policy-setting subroutine
                               1964                 :                :  *      Mark a namespace as to be dumped or not
                               1965                 :                :  */
                               1966                 :                : static void
 3440 sfrost@snowman.net       1967                 :           1434 : selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
                               1968                 :                : {
                               1969                 :                :     /*
                               1970                 :                :      * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
                               1971                 :                :      * and (for --clean) a DROP SCHEMA statement.  (In the absence of
                               1972                 :                :      * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
                               1973                 :                :      */
 1531 noah@leadboat.com        1974                 :           1434 :     nsinfo->create = true;
                               1975                 :                : 
                               1976                 :                :     /*
                               1977                 :                :      * If specific tables are being dumped, do not dump any complete
                               1978                 :                :      * namespaces. If specific namespaces are being dumped, dump just those
                               1979                 :                :      * namespaces. Otherwise, dump all non-system namespaces.
                               1980                 :                :      */
 6907 tgl@sss.pgh.pa.us        1981         [ +  + ]:           1434 :     if (table_include_oids.head != NULL)
 3440 sfrost@snowman.net       1982                 :             50 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
 6907 tgl@sss.pgh.pa.us        1983         [ +  + ]:           1384 :     else if (schema_include_oids.head != NULL)
 3440 sfrost@snowman.net       1984                 :            179 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
                               1985                 :            179 :             simple_oid_list_member(&schema_include_oids,
                               1986                 :                :                                    nsinfo->dobj.catId.oid) ?
                               1987         [ +  + ]:            179 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               1988         [ +  - ]:           1205 :     else if (fout->remoteVersion >= 90600 &&
 3285 tgl@sss.pgh.pa.us        1989         [ +  + ]:           1205 :              strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
                               1990                 :                :     {
                               1991                 :                :         /*
                               1992                 :                :          * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
                               1993                 :                :          * they are interesting (and not the original ACLs which were set at
                               1994                 :                :          * initdb time, see pg_init_privs).
                               1995                 :                :          */
 3440 sfrost@snowman.net       1996                 :            164 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
                               1997                 :                :     }
 6907 tgl@sss.pgh.pa.us        1998         [ +  + ]:           1041 :     else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
                               1999         [ +  + ]:            513 :              strcmp(nsinfo->dobj.name, "information_schema") == 0)
                               2000                 :                :     {
                               2001                 :                :         /* Other system schemas don't get dumped */
 3440 sfrost@snowman.net       2002                 :            692 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2003                 :                :     }
 2781 tgl@sss.pgh.pa.us        2004         [ +  + ]:            349 :     else if (strcmp(nsinfo->dobj.name, "public") == 0)
                               2005                 :                :     {
                               2006                 :                :         /*
                               2007                 :                :          * The public schema is a strange beast that sits in a sort of
                               2008                 :                :          * no-mans-land between being a system object and a user object.
                               2009                 :                :          * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
                               2010                 :                :          * a comment and an indication of ownership.  If the owner is the
                               2011                 :                :          * default, omit that superfluous DUMP_COMPONENT_DEFINITION.  Before
                               2012                 :                :          * v15, the default owner was BOOTSTRAP_SUPERUSERID.
                               2013                 :                :          */
 1531 noah@leadboat.com        2014                 :            160 :         nsinfo->create = false;
                               2015                 :            160 :         nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
 1458                          2016         [ +  + ]:            160 :         if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
 1531                          2017                 :            112 :             nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
 2781 tgl@sss.pgh.pa.us        2018                 :            160 :         nsinfo->dobj.dump_contains = DUMP_COMPONENT_ALL;
                               2019                 :                : 
                               2020                 :                :         /*
                               2021                 :                :          * Also, make like it has a comment even if it doesn't; this is so
                               2022                 :                :          * that we'll emit a command to drop the comment, if appropriate.
                               2023                 :                :          * (Without this, we'd not call dumpCommentExtended for it.)
                               2024                 :                :          */
 1370                          2025                 :            160 :         nsinfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                               2026                 :                :     }
                               2027                 :                :     else
 3440 sfrost@snowman.net       2028                 :            189 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
                               2029                 :                : 
                               2030                 :                :     /*
                               2031                 :                :      * In any case, a namespace can be excluded by an exclusion switch
                               2032                 :                :      */
                               2033   [ +  +  +  + ]:           1958 :     if (nsinfo->dobj.dump_contains &&
 6907 tgl@sss.pgh.pa.us        2034                 :            524 :         simple_oid_list_member(&schema_exclude_oids,
                               2035                 :                :                                nsinfo->dobj.catId.oid))
 3440 sfrost@snowman.net       2036                 :              3 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2037                 :                : 
                               2038                 :                :     /*
                               2039                 :                :      * If the schema belongs to an extension, allow extension membership to
                               2040                 :                :      * override the dump decision for the schema itself.  However, this does
                               2041                 :                :      * not change dump_contains, so this won't change what we do with objects
                               2042                 :                :      * within the schema.  (If they belong to the extension, they'll get
                               2043                 :                :      * suppressed by it, otherwise not.)
                               2044                 :                :      */
 3285 tgl@sss.pgh.pa.us        2045                 :           1434 :     (void) checkExtensionMembership(&nsinfo->dobj, fout);
 6907                          2046                 :           1434 : }
                               2047                 :                : 
                               2048                 :                : /*
                               2049                 :                :  * selectDumpableTable: policy-setting subroutine
                               2050                 :                :  *      Mark a table as to be dumped or not
                               2051                 :                :  */
                               2052                 :                : static void
 3440 sfrost@snowman.net       2053                 :          49126 : selectDumpableTable(TableInfo *tbinfo, Archive *fout)
                               2054                 :                : {
                               2055         [ +  + ]:          49126 :     if (checkExtensionMembership(&tbinfo->dobj, fout))
 3524 tgl@sss.pgh.pa.us        2056                 :            225 :         return;                 /* extension membership overrides all else */
                               2057                 :                : 
                               2058                 :                :     /*
                               2059                 :                :      * If specific tables are being dumped, dump just those tables; else, dump
                               2060                 :                :      * according to the parent namespace's dump flag.
                               2061                 :                :      */
 6907                          2062         [ +  + ]:          48901 :     if (table_include_oids.head != NULL)
                               2063                 :           5178 :         tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
                               2064                 :                :                                                    tbinfo->dobj.catId.oid) ?
 3440 sfrost@snowman.net       2065         [ +  + ]:           2589 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2066                 :                :     else
                               2067                 :          46312 :         tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
                               2068                 :                : 
                               2069                 :                :     /*
                               2070                 :                :      * In any case, a table can be excluded by an exclusion switch
                               2071                 :                :      */
 6907 tgl@sss.pgh.pa.us        2072   [ +  +  +  + ]:          80076 :     if (tbinfo->dobj.dump &&
                               2073                 :          31175 :         simple_oid_list_member(&table_exclude_oids,
                               2074                 :                :                                tbinfo->dobj.catId.oid))
 3440 sfrost@snowman.net       2075                 :             12 :         tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               2076                 :                : }
                               2077                 :                : 
                               2078                 :                : /*
                               2079                 :                :  * selectDumpableType: policy-setting subroutine
                               2080                 :                :  *      Mark a type as to be dumped or not
                               2081                 :                :  *
                               2082                 :                :  * If it's a table's rowtype or an autogenerated array type, we also apply a
                               2083                 :                :  * special type code to facilitate sorting into the desired order.  (We don't
                               2084                 :                :  * want to consider those to be ordinary types because that would bring tables
                               2085                 :                :  * up into the datatype part of the dump order.)  We still set the object's
                               2086                 :                :  * dump flag; that's not going to cause the dummy type to be dumped, but we
                               2087                 :                :  * need it so that casts involving such types will be dumped correctly -- see
                               2088                 :                :  * dumpCast.  This means the flag should be set the same as for the underlying
                               2089                 :                :  * object (the table or base type).
                               2090                 :                :  */
                               2091                 :                : static void
                               2092                 :         134755 : selectDumpableType(TypeInfo *tyinfo, Archive *fout)
                               2093                 :                : {
                               2094                 :                :     /* skip complex types, except for standalone composite types */
 5736 bruce@momjian.us         2095         [ +  + ]:         134755 :     if (OidIsValid(tyinfo->typrelid) &&
                               2096         [ +  + ]:          48387 :         tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
                               2097                 :                :     {
 5072 tgl@sss.pgh.pa.us        2098                 :          48199 :         TableInfo  *tytable = findTableByOid(tyinfo->typrelid);
                               2099                 :                : 
 5736 bruce@momjian.us         2100                 :          48199 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
 5072 tgl@sss.pgh.pa.us        2101         [ +  - ]:          48199 :         if (tytable != NULL)
                               2102                 :          48199 :             tyinfo->dobj.dump = tytable->dobj.dump;
                               2103                 :                :         else
 3440 sfrost@snowman.net       2104                 :UBC           0 :             tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
 5072 tgl@sss.pgh.pa.us        2105                 :CBC       48199 :         return;
                               2106                 :                :     }
                               2107                 :                : 
                               2108                 :                :     /* skip auto-generated array and multirange types */
 1721 akorotkov@postgresql     2109   [ +  +  +  + ]:          86556 :     if (tyinfo->isArray || tyinfo->isMultirange)
                               2110                 :                :     {
 5736 bruce@momjian.us         2111                 :          65920 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
                               2112                 :                : 
                               2113                 :                :         /*
                               2114                 :                :          * Fall through to set the dump flag; we assume that the subsequent
                               2115                 :                :          * rules will do the same thing as they would for the array's base
                               2116                 :                :          * type or multirange's range type.  (We cannot reliably look up the
                               2117                 :                :          * base type here, since getTypes may not have processed it yet.)
                               2118                 :                :          */
                               2119                 :                :     }
                               2120                 :                : 
 3440 sfrost@snowman.net       2121         [ +  + ]:          86556 :     if (checkExtensionMembership(&tyinfo->dobj, fout))
 3524 tgl@sss.pgh.pa.us        2122                 :            150 :         return;                 /* extension membership overrides all else */
                               2123                 :                : 
                               2124                 :                :     /* Dump based on if the contents of the namespace are being dumped */
 3440 sfrost@snowman.net       2125                 :          86406 :     tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
                               2126                 :                : }
                               2127                 :                : 
                               2128                 :                : /*
                               2129                 :                :  * selectDumpableDefaultACL: policy-setting subroutine
                               2130                 :                :  *      Mark a default ACL as to be dumped or not
                               2131                 :                :  *
                               2132                 :                :  * For per-schema default ACLs, dump if the schema is to be dumped.
                               2133                 :                :  * Otherwise dump if we are dumping "everything".  Note that dumpSchema
                               2134                 :                :  * and aclsSkip are checked separately.
                               2135                 :                :  */
                               2136                 :                : static void
 3524 tgl@sss.pgh.pa.us        2137                 :            218 : selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
                               2138                 :                : {
                               2139                 :                :     /* Default ACLs can't be extension members */
                               2140                 :                : 
 5815                          2141         [ +  + ]:            218 :     if (dinfo->dobj.namespace)
                               2142                 :                :         /* default ACLs are considered part of the namespace */
 3410 sfrost@snowman.net       2143                 :            102 :         dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
                               2144                 :                :     else
 3440                          2145                 :            116 :         dinfo->dobj.dump = dopt->include_everything ?
                               2146         [ +  + ]:            116 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
 5815 tgl@sss.pgh.pa.us        2147                 :            218 : }
                               2148                 :                : 
                               2149                 :                : /*
                               2150                 :                :  * selectDumpableCast: policy-setting subroutine
                               2151                 :                :  *      Mark a cast as to be dumped or not
                               2152                 :                :  *
                               2153                 :                :  * Casts do not belong to any particular namespace (since they haven't got
                               2154                 :                :  * names), nor do they have identifiable owners.  To distinguish user-defined
                               2155                 :                :  * casts from built-in ones, we must resort to checking whether the cast's
                               2156                 :                :  * OID is in the range reserved for initdb.
                               2157                 :                :  */
                               2158                 :                : static void
 3440 sfrost@snowman.net       2159                 :          43753 : selectDumpableCast(CastInfo *cast, Archive *fout)
                               2160                 :                : {
                               2161         [ -  + ]:          43753 :     if (checkExtensionMembership(&cast->dobj, fout))
 3524 tgl@sss.pgh.pa.us        2162                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2163                 :                : 
                               2164                 :                :     /*
                               2165                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
                               2166                 :                :      * support ACLs currently.
                               2167                 :                :      */
 3181 sfrost@snowman.net       2168         [ +  + ]:CBC       43753 :     if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3440                          2169                 :          43660 :         cast->dobj.dump = DUMP_COMPONENT_NONE;
                               2170                 :                :     else
                               2171                 :             93 :         cast->dobj.dump = fout->dopt->include_everything ?
                               2172         [ +  + ]:             93 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2173                 :                : }
                               2174                 :                : 
                               2175                 :                : /*
                               2176                 :                :  * selectDumpableProcLang: policy-setting subroutine
                               2177                 :                :  *      Mark a procedural language as to be dumped or not
                               2178                 :                :  *
                               2179                 :                :  * Procedural languages do not belong to any particular namespace.  To
                               2180                 :                :  * identify built-in languages, we must resort to checking whether the
                               2181                 :                :  * language's OID is in the range reserved for initdb.
                               2182                 :                :  */
                               2183                 :                : static void
                               2184                 :            236 : selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
                               2185                 :                : {
                               2186         [ +  + ]:            236 :     if (checkExtensionMembership(&plang->dobj, fout))
 3524 tgl@sss.pgh.pa.us        2187                 :            185 :         return;                 /* extension membership overrides all else */
                               2188                 :                : 
                               2189                 :                :     /*
                               2190                 :                :      * Only include procedural languages when we are dumping everything.
                               2191                 :                :      *
                               2192                 :                :      * For from-initdb procedural languages, only include ACLs, as we do for
                               2193                 :                :      * the pg_catalog namespace.  We need this because procedural languages do
                               2194                 :                :      * not live in any namespace.
                               2195                 :                :      */
 3410 sfrost@snowman.net       2196         [ +  + ]:             51 :     if (!fout->dopt->include_everything)
 3440                          2197                 :              8 :         plang->dobj.dump = DUMP_COMPONENT_NONE;
                               2198                 :                :     else
                               2199                 :                :     {
 3181                          2200         [ -  + ]:             43 :         if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3410 sfrost@snowman.net       2201                 :UBC           0 :             plang->dobj.dump = fout->remoteVersion < 90600 ?
                               2202         [ #  # ]:              0 :                 DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL;
                               2203                 :                :         else
 3410 sfrost@snowman.net       2204                 :CBC          43 :             plang->dobj.dump = DUMP_COMPONENT_ALL;
                               2205                 :                :     }
                               2206                 :                : }
                               2207                 :                : 
                               2208                 :                : /*
                               2209                 :                :  * selectDumpableAccessMethod: policy-setting subroutine
                               2210                 :                :  *      Mark an access method as to be dumped or not
                               2211                 :                :  *
                               2212                 :                :  * Access methods do not belong to any particular namespace.  To identify
                               2213                 :                :  * built-in access methods, we must resort to checking whether the
                               2214                 :                :  * method's OID is in the range reserved for initdb.
                               2215                 :                :  */
                               2216                 :                : static void
 3440                          2217                 :           1429 : selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
                               2218                 :                : {
                               2219                 :                :     /* see getAccessMethods() comment about v9.6. */
   37 noah@leadboat.com        2220         [ -  + ]:           1429 :     if (fout->remoteVersion < 90600)
                               2221                 :                :     {
   37 noah@leadboat.com        2222                 :UBC           0 :         method->dobj.dump = DUMP_COMPONENT_NONE;
                               2223                 :              0 :         return;
                               2224                 :                :     }
                               2225                 :                : 
 3440 sfrost@snowman.net       2226         [ +  + ]:CBC        1429 :     if (checkExtensionMembership(&method->dobj, fout))
 3454 alvherre@alvh.no-ip.     2227                 :             25 :         return;                 /* extension membership overrides all else */
                               2228                 :                : 
                               2229                 :                :     /*
                               2230                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
                               2231                 :                :      * they do not support ACLs currently.
                               2232                 :                :      */
 3181 sfrost@snowman.net       2233         [ +  + ]:           1404 :     if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3440                          2234                 :           1295 :         method->dobj.dump = DUMP_COMPONENT_NONE;
                               2235                 :                :     else
                               2236                 :            109 :         method->dobj.dump = fout->dopt->include_everything ?
                               2237         [ +  + ]:            109 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2238                 :                : }
                               2239                 :                : 
                               2240                 :                : /*
                               2241                 :                :  * selectDumpableExtension: policy-setting subroutine
                               2242                 :                :  *      Mark an extension as to be dumped or not
                               2243                 :                :  *
                               2244                 :                :  * Built-in extensions should be skipped except for checking ACLs, since we
                               2245                 :                :  * assume those will already be installed in the target database.  We identify
                               2246                 :                :  * such extensions by their having OIDs in the range reserved for initdb.
                               2247                 :                :  * We dump all user-added extensions by default.  No extensions are dumped
                               2248                 :                :  * if include_everything is false (i.e., a --schema or --table switch was
                               2249                 :                :  * given), except if --extension specifies a list of extensions to dump.
                               2250                 :                :  */
                               2251                 :                : static void
 3524 tgl@sss.pgh.pa.us        2252                 :            211 : selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
                               2253                 :                : {
                               2254                 :                :     /*
                               2255                 :                :      * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
                               2256                 :                :      * change permissions on their member objects, if they wish to, and have
                               2257                 :                :      * those changes preserved.
                               2258                 :                :      */
 2781                          2259         [ +  + ]:            211 :     if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 3410 sfrost@snowman.net       2260                 :            186 :         extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
                               2261                 :                :     else
                               2262                 :                :     {
                               2263                 :                :         /* check if there is a list of extensions to dump */
 1620 michael@paquier.xyz      2264         [ +  + ]:             25 :         if (extension_include_oids.head != NULL)
                               2265                 :              4 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2266                 :              4 :                 simple_oid_list_member(&extension_include_oids,
                               2267                 :                :                                        extinfo->dobj.catId.oid) ?
                               2268         [ +  + ]:              4 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2269                 :                :         else
                               2270                 :             21 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2271                 :             21 :                 dopt->include_everything ?
                               2272         [ +  + ]:             21 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2273                 :                : 
                               2274                 :                :         /* check that the extension is not explicitly excluded */
  535 dean.a.rasheed@gmail     2275   [ +  +  +  + ]:             46 :         if (extinfo->dobj.dump &&
                               2276                 :             21 :             simple_oid_list_member(&extension_exclude_oids,
                               2277                 :                :                                    extinfo->dobj.catId.oid))
                               2278                 :              2 :             extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
                               2279                 :                :     }
 5300 tgl@sss.pgh.pa.us        2280                 :            211 : }
                               2281                 :                : 
                               2282                 :                : /*
                               2283                 :                :  * selectDumpablePublicationObject: policy-setting subroutine
                               2284                 :                :  *      Mark a publication object as to be dumped or not
                               2285                 :                :  *
                               2286                 :                :  * A publication can have schemas and tables which have schemas, but those are
                               2287                 :                :  * ignored in decision making, because publications are only dumped when we are
                               2288                 :                :  * dumping everything.
                               2289                 :                :  */
                               2290                 :                : static void
 1410 akapila@postgresql.o     2291                 :            529 : selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
                               2292                 :                : {
 3091 peter_e@gmx.net          2293         [ -  + ]:            529 :     if (checkExtensionMembership(dobj, fout))
 3091 peter_e@gmx.net          2294                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2295                 :                : 
 3091 peter_e@gmx.net          2296                 :CBC         529 :     dobj->dump = fout->dopt->include_everything ?
                               2297         [ +  + ]:            529 :         DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2298                 :                : }
                               2299                 :                : 
                               2300                 :                : /*
                               2301                 :                :  * selectDumpableStatisticsObject: policy-setting subroutine
                               2302                 :                :  *      Mark an extended statistics object as to be dumped or not
                               2303                 :                :  *
                               2304                 :                :  * We dump an extended statistics object if the schema it's in and the table
                               2305                 :                :  * it's for are being dumped.  (This'll need more thought if statistics
                               2306                 :                :  * objects ever support cross-table stats.)
                               2307                 :                :  */
                               2308                 :                : static void
  617 tgl@sss.pgh.pa.us        2309                 :            181 : selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
                               2310                 :                : {
                               2311         [ -  + ]:            181 :     if (checkExtensionMembership(&sobj->dobj, fout))
  617 tgl@sss.pgh.pa.us        2312                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2313                 :                : 
  617 tgl@sss.pgh.pa.us        2314                 :CBC         181 :     sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
                               2315         [ +  - ]:            181 :     if (sobj->stattable == NULL ||
                               2316         [ +  + ]:            181 :         !(sobj->stattable->dobj.dump & DUMP_COMPONENT_DEFINITION))
                               2317                 :             28 :         sobj->dobj.dump = DUMP_COMPONENT_NONE;
                               2318                 :                : }
                               2319                 :                : 
                               2320                 :                : /*
                               2321                 :                :  * selectDumpableObject: policy-setting subroutine
                               2322                 :                :  *      Mark a generic dumpable object as to be dumped or not
                               2323                 :                :  *
                               2324                 :                :  * Use this only for object types without a special-case routine above.
                               2325                 :                :  */
                               2326                 :                : static void
 3440 sfrost@snowman.net       2327                 :         531163 : selectDumpableObject(DumpableObject *dobj, Archive *fout)
                               2328                 :                : {
                               2329         [ +  + ]:         531163 :     if (checkExtensionMembership(dobj, fout))
 3524 tgl@sss.pgh.pa.us        2330                 :            183 :         return;                 /* extension membership overrides all else */
                               2331                 :                : 
                               2332                 :                :     /*
                               2333                 :                :      * Default policy is to dump if parent namespace is dumpable, or for
                               2334                 :                :      * non-namespace-associated items, dump if we're dumping "everything".
                               2335                 :                :      */
 7128                          2336         [ +  + ]:         530980 :     if (dobj->namespace)
 3440 sfrost@snowman.net       2337                 :         530264 :         dobj->dump = dobj->namespace->dobj.dump_contains;
                               2338                 :                :     else
                               2339                 :            716 :         dobj->dump = fout->dopt->include_everything ?
                               2340         [ +  + ]:            716 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2341                 :                : }
                               2342                 :                : 
                               2343                 :                : /*
                               2344                 :                :  *  Dump a table's contents for loading using the COPY command
                               2345                 :                :  *  - this routine is called by the Archiver when it wants the table
                               2346                 :                :  *    to be dumped.
                               2347                 :                :  */
                               2348                 :                : static int
 1669 peter@eisentraut.org     2349                 :           4327 : dumpTableData_copy(Archive *fout, const void *dcontext)
                               2350                 :                : {
 7945 tgl@sss.pgh.pa.us        2351                 :           4327 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2352                 :           4327 :     TableInfo  *tbinfo = tdinfo->tdtable;
 7857                          2353                 :           4327 :     const char *classname = tbinfo->dobj.name;
 8520                          2354                 :           4327 :     PQExpBuffer q = createPQExpBuffer();
                               2355                 :                : 
                               2356                 :                :     /*
                               2357                 :                :      * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
                               2358                 :                :      * which uses it already.
                               2359                 :                :      */
 4549 andrew@dunslane.net      2360                 :           4327 :     PQExpBuffer clistBuf = createPQExpBuffer();
 4951 rhaas@postgresql.org     2361                 :           4327 :     PGconn     *conn = GetConnection(fout);
                               2362                 :                :     PGresult   *res;
                               2363                 :                :     int         ret;
                               2364                 :                :     char       *copybuf;
                               2365                 :                :     const char *column_list;
                               2366                 :                : 
 2350 peter@eisentraut.org     2367                 :           4327 :     pg_log_info("dumping contents of table \"%s.%s\"",
                               2368                 :                :                 tbinfo->dobj.namespace->dobj.name, classname);
                               2369                 :                : 
                               2370                 :                :     /*
                               2371                 :                :      * Specify the column list explicitly so that we have no possibility of
                               2372                 :                :      * retrieving data in the wrong column order.  (The default column
                               2373                 :                :      * ordering of COPY will not be what we want in certain corner cases
                               2374                 :                :      * involving ADD COLUMN and inheritance.)
                               2375                 :                :      */
 3251 tgl@sss.pgh.pa.us        2376                 :           4327 :     column_list = fmtCopyColumnList(tbinfo, clistBuf);
                               2377                 :                : 
                               2378                 :                :     /*
                               2379                 :                :      * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
                               2380                 :                :      * a filter condition was specified.  For other cases a simple COPY
                               2381                 :                :      * suffices.
                               2382                 :                :      */
 1991 alvherre@alvh.no-ip.     2383   [ +  +  +  + ]:           4327 :     if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                               2384                 :                :     {
                               2385                 :                :         /* Temporary allows to access to foreign tables to dump data */
  397 msawada@postgresql.o     2386         [ +  + ]:             37 :         if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                               2387                 :              1 :             set_restrict_relation_kind(fout, "view");
                               2388                 :                : 
 5324 tgl@sss.pgh.pa.us        2389                 :             37 :         appendPQExpBufferStr(q, "COPY (SELECT ");
                               2390                 :                :         /* klugery to get rid of parens in column list */
                               2391         [ +  - ]:             37 :         if (strlen(column_list) > 2)
                               2392                 :                :         {
                               2393                 :             37 :             appendPQExpBufferStr(q, column_list + 1);
                               2394                 :             37 :             q->data[q->len - 1] = ' ';
                               2395                 :                :         }
                               2396                 :                :         else
 5324 tgl@sss.pgh.pa.us        2397                 :UBC           0 :             appendPQExpBufferStr(q, "* ");
                               2398                 :                : 
 5324 tgl@sss.pgh.pa.us        2399                 :CBC          74 :         appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
 2749                          2400                 :             37 :                           fmtQualifiedDumpable(tbinfo),
 1991 alvherre@alvh.no-ip.     2401         [ +  + ]:             37 :                           tdinfo->filtercond ? tdinfo->filtercond : "");
                               2402                 :                :     }
                               2403                 :                :     else
                               2404                 :                :     {
 8451 bruce@momjian.us         2405                 :           4290 :         appendPQExpBuffer(q, "COPY %s %s TO stdout;",
 2749 tgl@sss.pgh.pa.us        2406                 :           4290 :                           fmtQualifiedDumpable(tbinfo),
                               2407                 :                :                           column_list);
                               2408                 :                :     }
 4960 rhaas@postgresql.org     2409                 :           4327 :     res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
 7127 tgl@sss.pgh.pa.us        2410                 :           4326 :     PQclear(res);
 4549 andrew@dunslane.net      2411                 :           4326 :     destroyPQExpBuffer(clistBuf);
                               2412                 :                : 
                               2413                 :                :     for (;;)
                               2414                 :                :     {
 4951 rhaas@postgresql.org     2415                 :        1813263 :         ret = PQgetCopyData(conn, &copybuf, 0);
                               2416                 :                : 
 7127 tgl@sss.pgh.pa.us        2417         [ +  + ]:        1813263 :         if (ret < 0)
                               2418                 :           4326 :             break;              /* done or error */
                               2419                 :                : 
                               2420         [ +  - ]:        1808937 :         if (copybuf)
                               2421                 :                :         {
                               2422                 :        1808937 :             WriteData(fout, copybuf, ret);
                               2423                 :        1808937 :             PQfreemem(copybuf);
                               2424                 :                :         }
                               2425                 :                : 
                               2426                 :                :         /* ----------
                               2427                 :                :          * THROTTLE:
                               2428                 :                :          *
                               2429                 :                :          * There was considerable discussion in late July, 2000 regarding
                               2430                 :                :          * slowing down pg_dump when backing up large tables. Users with both
                               2431                 :                :          * slow & fast (multi-processor) machines experienced performance
                               2432                 :                :          * degradation when doing a backup.
                               2433                 :                :          *
                               2434                 :                :          * Initial attempts based on sleeping for a number of ms for each ms
                               2435                 :                :          * of work were deemed too complex, then a simple 'sleep in each loop'
                               2436                 :                :          * implementation was suggested. The latter failed because the loop
                               2437                 :                :          * was too tight. Finally, the following was implemented:
                               2438                 :                :          *
                               2439                 :                :          * If throttle is non-zero, then
                               2440                 :                :          *      See how long since the last sleep.
                               2441                 :                :          *      Work out how long to sleep (based on ratio).
                               2442                 :                :          *      If sleep is more than 100ms, then
                               2443                 :                :          *          sleep
                               2444                 :                :          *          reset timer
                               2445                 :                :          *      EndIf
                               2446                 :                :          * EndIf
                               2447                 :                :          *
                               2448                 :                :          * where the throttle value was the number of ms to sleep per ms of
                               2449                 :                :          * work. The calculation was done in each loop.
                               2450                 :                :          *
                               2451                 :                :          * Most of the hard work is done in the backend, and this solution
                               2452                 :                :          * still did not work particularly well: on slow machines, the ratio
                               2453                 :                :          * was 50:1, and on medium paced machines, 1:1, and on fast
                               2454                 :                :          * multi-processor machines, it had little or no effect, for reasons
                               2455                 :                :          * that were unclear.
                               2456                 :                :          *
                               2457                 :                :          * Further discussion ensued, and the proposal was dropped.
                               2458                 :                :          *
                               2459                 :                :          * For those people who want this feature, it can be implemented using
                               2460                 :                :          * gettimeofday in each loop, calculating the time since last sleep,
                               2461                 :                :          * multiplying that by the sleep ratio, then if the result is more
                               2462                 :                :          * than a preset 'minimum sleep time' (say 100ms), call the 'select'
                               2463                 :                :          * function to sleep for a subsecond period ie.
                               2464                 :                :          *
                               2465                 :                :          * select(0, NULL, NULL, NULL, &tvi);
                               2466                 :                :          *
                               2467                 :                :          * This will return after the interval specified in the structure tvi.
                               2468                 :                :          * Finally, call gettimeofday again to save the 'last sleep time'.
                               2469                 :                :          * ----------
                               2470                 :                :          */
                               2471                 :                :     }
 8420 peter_e@gmx.net          2472                 :           4326 :     archprintf(fout, "\\.\n\n\n");
                               2473                 :                : 
 7127 tgl@sss.pgh.pa.us        2474         [ -  + ]:           4326 :     if (ret == -2)
                               2475                 :                :     {
                               2476                 :                :         /* copy data transfer failed */
 2350 peter@eisentraut.org     2477                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
 1247 tgl@sss.pgh.pa.us        2478                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2479                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 4951 rhaas@postgresql.org     2480                 :              0 :         exit_nicely(1);
                               2481                 :                :     }
                               2482                 :                : 
                               2483                 :                :     /* Check command status and return to normal libpq state */
 4951 rhaas@postgresql.org     2484                 :CBC        4326 :     res = PQgetResult(conn);
 4960                          2485         [ -  + ]:           4326 :     if (PQresultStatus(res) != PGRES_COMMAND_OK)
                               2486                 :                :     {
 2350 peter@eisentraut.org     2487                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
 1247 tgl@sss.pgh.pa.us        2488                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2489                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 4951 rhaas@postgresql.org     2490                 :              0 :         exit_nicely(1);
                               2491                 :                :     }
 8467 bruce@momjian.us         2492                 :CBC        4326 :     PQclear(res);
                               2493                 :                : 
                               2494                 :                :     /* Do this to ensure we've pumped libpq back to idle state */
 3383 tgl@sss.pgh.pa.us        2495         [ -  + ]:           4326 :     if (PQgetResult(conn) != NULL)
 2350 peter@eisentraut.org     2496                 :UBC           0 :         pg_log_warning("unexpected extra results during COPY of table \"%s\"",
                               2497                 :                :                        classname);
                               2498                 :                : 
 8520 tgl@sss.pgh.pa.us        2499                 :CBC        4326 :     destroyPQExpBuffer(q);
                               2500                 :                : 
                               2501                 :                :     /* Revert back the setting */
  397 msawada@postgresql.o     2502         [ -  + ]:           4326 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  397 msawada@postgresql.o     2503                 :UBC           0 :         set_restrict_relation_kind(fout, "view, foreign-table");
                               2504                 :                : 
 8520 tgl@sss.pgh.pa.us        2505                 :CBC        4326 :     return 1;
                               2506                 :                : }
                               2507                 :                : 
                               2508                 :                : /*
                               2509                 :                :  * Dump table data using INSERT commands.
                               2510                 :                :  *
                               2511                 :                :  * Caution: when we restore from an archive file direct to database, the
                               2512                 :                :  * INSERT commands emitted by this function have to be parsed by
                               2513                 :                :  * pg_backup_db.c's ExecuteSimpleCommands(), which will not handle comments,
                               2514                 :                :  * E'' strings, or dollar-quoted strings.  So don't emit anything like that.
                               2515                 :                :  */
                               2516                 :                : static int
 1669 peter@eisentraut.org     2517                 :             85 : dumpTableData_insert(Archive *fout, const void *dcontext)
                               2518                 :                : {
 7945 tgl@sss.pgh.pa.us        2519                 :             85 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2520                 :             85 :     TableInfo  *tbinfo = tdinfo->tdtable;
 3524                          2521                 :             85 :     DumpOptions *dopt = fout->dopt;
 8520                          2522                 :             85 :     PQExpBuffer q = createPQExpBuffer();
 4313                          2523                 :             85 :     PQExpBuffer insertStmt = NULL;
                               2524                 :                :     char       *attgenerated;
                               2525                 :                :     PGresult   *res;
                               2526                 :                :     int         nfields,
                               2527                 :                :                 i;
 2375 alvherre@alvh.no-ip.     2528                 :             85 :     int         rows_per_statement = dopt->dump_inserts;
                               2529                 :             85 :     int         rows_this_statement = 0;
                               2530                 :                : 
                               2531                 :                :     /* Temporary allows to access to foreign tables to dump data */
  397 msawada@postgresql.o     2532         [ -  + ]:             85 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  397 msawada@postgresql.o     2533                 :UBC           0 :         set_restrict_relation_kind(fout, "view");
                               2534                 :                : 
                               2535                 :                :     /*
                               2536                 :                :      * If we're going to emit INSERTs with column names, the most efficient
                               2537                 :                :      * way to deal with generated columns is to exclude them entirely.  For
                               2538                 :                :      * INSERTs without column names, we have to emit DEFAULT rather than the
                               2539                 :                :      * actual column value --- but we can save a few cycles by fetching nulls
                               2540                 :                :      * rather than the uninteresting-to-us value.
                               2541                 :                :      */
 1384 tgl@sss.pgh.pa.us        2542                 :CBC          85 :     attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
                               2543                 :             85 :     appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
                               2544                 :             85 :     nfields = 0;
                               2545         [ +  + ]:            261 :     for (i = 0; i < tbinfo->numatts; i++)
                               2546                 :                :     {
                               2547         [ +  + ]:            176 :         if (tbinfo->attisdropped[i])
                               2548                 :              2 :             continue;
                               2549   [ +  +  +  + ]:            174 :         if (tbinfo->attgenerated[i] && dopt->column_inserts)
                               2550                 :              8 :             continue;
                               2551         [ +  + ]:            166 :         if (nfields > 0)
                               2552                 :             88 :             appendPQExpBufferStr(q, ", ");
                               2553         [ +  + ]:            166 :         if (tbinfo->attgenerated[i])
                               2554                 :              8 :             appendPQExpBufferStr(q, "NULL");
                               2555                 :                :         else
                               2556                 :            158 :             appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
                               2557                 :            166 :         attgenerated[nfields] = tbinfo->attgenerated[i];
                               2558                 :            166 :         nfields++;
                               2559                 :                :     }
                               2560                 :                :     /* Servers before 9.4 will complain about zero-column SELECT */
                               2561         [ +  + ]:             85 :     if (nfields == 0)
                               2562                 :              7 :         appendPQExpBufferStr(q, "NULL");
                               2563                 :             85 :     appendPQExpBuffer(q, " FROM ONLY %s",
 2749                          2564                 :             85 :                       fmtQualifiedDumpable(tbinfo));
 5324                          2565         [ -  + ]:             85 :     if (tdinfo->filtercond)
 5324 tgl@sss.pgh.pa.us        2566                 :UBC           0 :         appendPQExpBuffer(q, " %s", tdinfo->filtercond);
                               2567                 :                : 
 4960 rhaas@postgresql.org     2568                 :CBC          85 :     ExecuteSqlStatement(fout, q->data);
                               2569                 :                : 
                               2570                 :                :     while (1)
                               2571                 :                :     {
                               2572                 :            137 :         res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
                               2573                 :                :                               PGRES_TUPLES_OK);
                               2574                 :                : 
                               2575                 :                :         /* cross-check field count, allowing for dummy NULL if any */
 1384 tgl@sss.pgh.pa.us        2576   [ +  +  +  - ]:            137 :         if (nfields != PQnfields(res) &&
                               2577         [ -  + ]:             10 :             !(nfields == 0 && PQnfields(res) == 1))
 1247 tgl@sss.pgh.pa.us        2578                 :UBC           0 :             pg_fatal("wrong number of fields retrieved from table \"%s\"",
                               2579                 :                :                      tbinfo->dobj.name);
                               2580                 :                : 
                               2581                 :                :         /*
                               2582                 :                :          * First time through, we build as much of the INSERT statement as
                               2583                 :                :          * possible in "insertStmt", which we can then just print for each
                               2584                 :                :          * statement. If the table happens to have zero dumpable columns then
                               2585                 :                :          * this will be a complete statement, otherwise it will end in
                               2586                 :                :          * "VALUES" and be ready to have the row's column values printed.
                               2587                 :                :          */
 2375 alvherre@alvh.no-ip.     2588         [ +  + ]:CBC         137 :         if (insertStmt == NULL)
                               2589                 :                :         {
                               2590                 :                :             TableInfo  *targettab;
                               2591                 :                : 
                               2592                 :             85 :             insertStmt = createPQExpBuffer();
                               2593                 :                : 
                               2594                 :                :             /*
                               2595                 :                :              * When load-via-partition-root is set or forced, get the root
                               2596                 :                :              * table name for the partition table, so that we can reload data
                               2597                 :                :              * through the root table.
                               2598                 :                :              */
  904 tgl@sss.pgh.pa.us        2599         [ +  + ]:             85 :             if (tbinfo->ispartition &&
                               2600   [ +  -  +  + ]:             48 :                 (dopt->load_via_partition_root ||
                               2601                 :             24 :                  forcePartitionRootLoad(tbinfo)))
 2375 alvherre@alvh.no-ip.     2602                 :              7 :                 targettab = getRootTableInfo(tbinfo);
                               2603                 :                :             else
                               2604                 :             78 :                 targettab = tbinfo;
                               2605                 :                : 
                               2606                 :             85 :             appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
                               2607                 :             85 :                               fmtQualifiedDumpable(targettab));
                               2608                 :                : 
                               2609                 :                :             /* corner case for zero-column table */
                               2610         [ +  + ]:             85 :             if (nfields == 0)
                               2611                 :                :             {
                               2612                 :              7 :                 appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
                               2613                 :                :             }
                               2614                 :                :             else
                               2615                 :                :             {
                               2616                 :                :                 /* append the list of column names if required */
                               2617         [ +  + ]:             78 :                 if (dopt->column_inserts)
                               2618                 :                :                 {
                               2619                 :             35 :                     appendPQExpBufferChar(insertStmt, '(');
                               2620         [ +  + ]:            105 :                     for (int field = 0; field < nfields; field++)
                               2621                 :                :                     {
                               2622         [ +  + ]:             70 :                         if (field > 0)
                               2623                 :             35 :                             appendPQExpBufferStr(insertStmt, ", ");
                               2624                 :             70 :                         appendPQExpBufferStr(insertStmt,
                               2625                 :             70 :                                              fmtId(PQfname(res, field)));
                               2626                 :                :                     }
                               2627                 :             35 :                     appendPQExpBufferStr(insertStmt, ") ");
                               2628                 :                :                 }
                               2629                 :                : 
                               2630         [ +  + ]:             78 :                 if (tbinfo->needs_override)
                               2631                 :              2 :                     appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
                               2632                 :                : 
                               2633                 :             78 :                 appendPQExpBufferStr(insertStmt, "VALUES");
                               2634                 :                :             }
                               2635                 :                :         }
                               2636                 :                : 
                               2637         [ +  + ]:           3408 :         for (int tuple = 0; tuple < PQntuples(res); tuple++)
                               2638                 :                :         {
                               2639                 :                :             /* Write the INSERT if not in the middle of a multi-row INSERT. */
                               2640         [ +  + ]:           3271 :             if (rows_this_statement == 0)
                               2641                 :           3265 :                 archputs(insertStmt->data, fout);
                               2642                 :                : 
                               2643                 :                :             /*
                               2644                 :                :              * If it is zero-column table then we've already written the
                               2645                 :                :              * complete statement, which will mean we've disobeyed
                               2646                 :                :              * --rows-per-insert when it's set greater than 1.  We do support
                               2647                 :                :              * a way to make this multi-row with: SELECT UNION ALL SELECT
                               2648                 :                :              * UNION ALL ... but that's non-standard so we should avoid it
                               2649                 :                :              * given that using INSERTs is mostly only ever needed for
                               2650                 :                :              * cross-database exports.
                               2651                 :                :              */
 4313 tgl@sss.pgh.pa.us        2652         [ +  + ]:           3271 :             if (nfields == 0)
                               2653                 :              6 :                 continue;
                               2654                 :                : 
                               2655                 :                :             /* Emit a row heading */
 2375 alvherre@alvh.no-ip.     2656         [ +  + ]:           3265 :             if (rows_per_statement == 1)
                               2657                 :           3256 :                 archputs(" (", fout);
                               2658         [ +  + ]:              9 :             else if (rows_this_statement > 0)
                               2659                 :              6 :                 archputs(",\n\t(", fout);
                               2660                 :                :             else
                               2661                 :              3 :                 archputs("\n\t(", fout);
                               2662                 :                : 
                               2663         [ +  + ]:           9849 :             for (int field = 0; field < nfields; field++)
                               2664                 :                :             {
 8520 tgl@sss.pgh.pa.us        2665         [ +  + ]:           6584 :                 if (field > 0)
 4313                          2666                 :           3319 :                     archputs(", ", fout);
 1384                          2667         [ +  + ]:           6584 :                 if (attgenerated[field])
                               2668                 :                :                 {
 2352 peter@eisentraut.org     2669                 :              2 :                     archputs("DEFAULT", fout);
                               2670                 :              2 :                     continue;
                               2671                 :                :                 }
 8520 tgl@sss.pgh.pa.us        2672         [ +  + ]:           6582 :                 if (PQgetisnull(res, tuple, field))
                               2673                 :                :                 {
 4313                          2674                 :             83 :                     archputs("NULL", fout);
 8520                          2675                 :             83 :                     continue;
                               2676                 :                :                 }
                               2677                 :                : 
                               2678                 :                :                 /* XXX This code is partially duplicated in ruleutils.c */
                               2679   [ +  +  +  + ]:           6499 :                 switch (PQftype(res, field))
                               2680                 :                :                 {
                               2681                 :           4469 :                     case INT2OID:
                               2682                 :                :                     case INT4OID:
                               2683                 :                :                     case INT8OID:
                               2684                 :                :                     case OIDOID:
                               2685                 :                :                     case FLOAT4OID:
                               2686                 :                :                     case FLOAT8OID:
                               2687                 :                :                     case NUMERICOID:
                               2688                 :                :                         {
                               2689                 :                :                             /*
                               2690                 :                :                              * These types are printed without quotes unless
                               2691                 :                :                              * they contain values that aren't accepted by the
                               2692                 :                :                              * scanner unquoted (e.g., 'NaN').  Note that
                               2693                 :                :                              * strtod() and friends might accept NaN, so we
                               2694                 :                :                              * can't use that to test.
                               2695                 :                :                              *
                               2696                 :                :                              * In reality we only need to defend against
                               2697                 :                :                              * infinity and NaN, so we need not get too crazy
                               2698                 :                :                              * about pattern matching here.
                               2699                 :                :                              */
 8403 bruce@momjian.us         2700                 :           4469 :                             const char *s = PQgetvalue(res, tuple, field);
                               2701                 :                : 
                               2702         [ +  + ]:           4469 :                             if (strspn(s, "0123456789 +-eE.") == strlen(s))
 4313 tgl@sss.pgh.pa.us        2703                 :           4467 :                                 archputs(s, fout);
                               2704                 :                :                             else
 8403 bruce@momjian.us         2705                 :              2 :                                 archprintf(fout, "'%s'", s);
                               2706                 :                :                         }
                               2707                 :           4469 :                         break;
                               2708                 :                : 
 8520 tgl@sss.pgh.pa.us        2709                 :              2 :                     case BITOID:
                               2710                 :                :                     case VARBITOID:
                               2711                 :              2 :                         archprintf(fout, "B'%s'",
                               2712                 :                :                                    PQgetvalue(res, tuple, field));
                               2713                 :              2 :                         break;
                               2714                 :                : 
 8420 peter_e@gmx.net          2715                 :              4 :                     case BOOLOID:
 8403 bruce@momjian.us         2716         [ +  + ]:              4 :                         if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
 4313 tgl@sss.pgh.pa.us        2717                 :              2 :                             archputs("true", fout);
                               2718                 :                :                         else
                               2719                 :              2 :                             archputs("false", fout);
 8420 peter_e@gmx.net          2720                 :              4 :                         break;
                               2721                 :                : 
                               2722                 :           2024 :                     default:
                               2723                 :                :                         /* All other types are printed as string literals. */
 8520 tgl@sss.pgh.pa.us        2724                 :           2024 :                         resetPQExpBuffer(q);
 7041                          2725                 :           2024 :                         appendStringLiteralAH(q,
                               2726                 :                :                                               PQgetvalue(res, tuple, field),
                               2727                 :                :                                               fout);
 7528                          2728                 :           2024 :                         archputs(q->data, fout);
 8520                          2729                 :           2024 :                         break;
                               2730                 :                :                 }
                               2731                 :                :             }
                               2732                 :                : 
                               2733                 :                :             /* Terminate the row ... */
 2375 alvherre@alvh.no-ip.     2734                 :           3265 :             archputs(")", fout);
                               2735                 :                : 
                               2736                 :                :             /* ... and the statement, if the target no. of rows is reached */
                               2737         [ +  + ]:           3265 :             if (++rows_this_statement >= rows_per_statement)
                               2738                 :                :             {
                               2739         [ -  + ]:           3258 :                 if (dopt->do_nothing)
 2375 alvherre@alvh.no-ip.     2740                 :UBC           0 :                     archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2741                 :                :                 else
 2375 alvherre@alvh.no-ip.     2742                 :CBC        3258 :                     archputs(";\n", fout);
                               2743                 :                :                 /* Reset the row counter */
                               2744                 :           3258 :                 rows_this_statement = 0;
                               2745                 :                :             }
                               2746                 :                :         }
                               2747                 :                : 
 4960 rhaas@postgresql.org     2748         [ +  + ]:            137 :         if (PQntuples(res) <= 0)
                               2749                 :                :         {
                               2750                 :             85 :             PQclear(res);
                               2751                 :             85 :             break;
                               2752                 :                :         }
                               2753                 :             52 :         PQclear(res);
                               2754                 :                :     }
                               2755                 :                : 
                               2756                 :                :     /* Terminate any statements that didn't make the row count. */
 2375 alvherre@alvh.no-ip.     2757         [ +  + ]:             85 :     if (rows_this_statement > 0)
                               2758                 :                :     {
                               2759         [ -  + ]:              1 :         if (dopt->do_nothing)
 2375 alvherre@alvh.no-ip.     2760                 :UBC           0 :             archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2761                 :                :         else
 2375 alvherre@alvh.no-ip.     2762                 :CBC           1 :             archputs(";\n", fout);
                               2763                 :                :     }
                               2764                 :                : 
 4313 tgl@sss.pgh.pa.us        2765                 :             85 :     archputs("\n\n", fout);
                               2766                 :                : 
 4960 rhaas@postgresql.org     2767                 :             85 :     ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
                               2768                 :                : 
 8520 tgl@sss.pgh.pa.us        2769                 :             85 :     destroyPQExpBuffer(q);
 4313                          2770         [ +  - ]:             85 :     if (insertStmt != NULL)
                               2771                 :             85 :         destroyPQExpBuffer(insertStmt);
 1384                          2772                 :             85 :     free(attgenerated);
                               2773                 :                : 
                               2774                 :                :     /* Revert back the setting */
  397 msawada@postgresql.o     2775         [ -  + ]:             85 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
  397 msawada@postgresql.o     2776                 :UBC           0 :         set_restrict_relation_kind(fout, "view, foreign-table");
                               2777                 :                : 
 8520 tgl@sss.pgh.pa.us        2778                 :CBC          85 :     return 1;
                               2779                 :                : }
                               2780                 :                : 
                               2781                 :                : /*
                               2782                 :                :  * getRootTableInfo:
                               2783                 :                :  *     get the root TableInfo for the given partition table.
                               2784                 :                :  */
                               2785                 :                : static TableInfo *
 1669 peter@eisentraut.org     2786                 :             91 : getRootTableInfo(const TableInfo *tbinfo)
                               2787                 :                : {
                               2788                 :                :     TableInfo  *parentTbinfo;
                               2789                 :                : 
 2945 rhaas@postgresql.org     2790         [ -  + ]:             91 :     Assert(tbinfo->ispartition);
                               2791         [ -  + ]:             91 :     Assert(tbinfo->numParents == 1);
                               2792                 :                : 
                               2793                 :             91 :     parentTbinfo = tbinfo->parents[0];
                               2794         [ -  + ]:             91 :     while (parentTbinfo->ispartition)
                               2795                 :                :     {
 2945 rhaas@postgresql.org     2796         [ #  # ]:UBC           0 :         Assert(parentTbinfo->numParents == 1);
                               2797                 :              0 :         parentTbinfo = parentTbinfo->parents[0];
                               2798                 :                :     }
                               2799                 :                : 
 2945 rhaas@postgresql.org     2800                 :CBC          91 :     return parentTbinfo;
                               2801                 :                : }
                               2802                 :                : 
                               2803                 :                : /*
                               2804                 :                :  * forcePartitionRootLoad
                               2805                 :                :  *     Check if we must force load_via_partition_root for this partition.
                               2806                 :                :  *
                               2807                 :                :  * This is required if any level of ancestral partitioned table has an
                               2808                 :                :  * unsafe partitioning scheme.
                               2809                 :                :  */
                               2810                 :                : static bool
  904 tgl@sss.pgh.pa.us        2811                 :           1102 : forcePartitionRootLoad(const TableInfo *tbinfo)
                               2812                 :                : {
                               2813                 :                :     TableInfo  *parentTbinfo;
                               2814                 :                : 
                               2815         [ -  + ]:           1102 :     Assert(tbinfo->ispartition);
                               2816         [ -  + ]:           1102 :     Assert(tbinfo->numParents == 1);
                               2817                 :                : 
                               2818                 :           1102 :     parentTbinfo = tbinfo->parents[0];
                               2819         [ +  + ]:           1102 :     if (parentTbinfo->unsafe_partitions)
                               2820                 :             91 :         return true;
                               2821         [ +  + ]:           1227 :     while (parentTbinfo->ispartition)
                               2822                 :                :     {
                               2823         [ -  + ]:            216 :         Assert(parentTbinfo->numParents == 1);
                               2824                 :            216 :         parentTbinfo = parentTbinfo->parents[0];
                               2825         [ -  + ]:            216 :         if (parentTbinfo->unsafe_partitions)
  904 tgl@sss.pgh.pa.us        2826                 :UBC           0 :             return true;
                               2827                 :                :     }
                               2828                 :                : 
  904 tgl@sss.pgh.pa.us        2829                 :CBC        1011 :     return false;
                               2830                 :                : }
                               2831                 :                : 
                               2832                 :                : /*
                               2833                 :                :  * dumpTableData -
                               2834                 :                :  *    dump the contents of a single table
                               2835                 :                :  *
                               2836                 :                :  * Actually, this just makes an ArchiveEntry for the table contents.
                               2837                 :                :  */
                               2838                 :                : static void
 1669 peter@eisentraut.org     2839                 :           4496 : dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
                               2840                 :                : {
 3524 tgl@sss.pgh.pa.us        2841                 :           4496 :     DumpOptions *dopt = fout->dopt;
 7945                          2842                 :           4496 :     TableInfo  *tbinfo = tdinfo->tdtable;
 5323                          2843                 :           4496 :     PQExpBuffer copyBuf = createPQExpBuffer();
 4549 andrew@dunslane.net      2844                 :           4496 :     PQExpBuffer clistBuf = createPQExpBuffer();
                               2845                 :                :     DataDumperPtr dumpFn;
  904 tgl@sss.pgh.pa.us        2846                 :           4496 :     char       *tdDefn = NULL;
                               2847                 :                :     char       *copyStmt;
                               2848                 :                :     const char *copyFrom;
                               2849                 :                : 
                               2850                 :                :     /* We had better have loaded per-column details about this table */
 1795                          2851         [ -  + ]:           4496 :     Assert(tbinfo->interesting);
                               2852                 :                : 
                               2853                 :                :     /*
                               2854                 :                :      * When load-via-partition-root is set or forced, get the root table name
                               2855                 :                :      * for the partition table, so that we can reload data through the root
                               2856                 :                :      * table.  Then construct a comment to be inserted into the TOC entry's
                               2857                 :                :      * defn field, so that such cases can be identified reliably.
                               2858                 :                :      */
  904                          2859         [ +  + ]:           4496 :     if (tbinfo->ispartition &&
                               2860   [ +  -  +  + ]:           2156 :         (dopt->load_via_partition_root ||
                               2861                 :           1078 :          forcePartitionRootLoad(tbinfo)))
                               2862                 :             84 :     {
                               2863                 :                :         TableInfo  *parentTbinfo;
                               2864                 :                :         char       *sanitized;
                               2865                 :                : 
                               2866                 :             84 :         parentTbinfo = getRootTableInfo(tbinfo);
                               2867                 :             84 :         copyFrom = fmtQualifiedDumpable(parentTbinfo);
   26 noah@leadboat.com        2868                 :             84 :         sanitized = sanitize_line(copyFrom, true);
  904 tgl@sss.pgh.pa.us        2869                 :             84 :         printfPQExpBuffer(copyBuf, "-- load via partition root %s",
                               2870                 :                :                           sanitized);
   26 noah@leadboat.com        2871                 :             84 :         free(sanitized);
  904 tgl@sss.pgh.pa.us        2872                 :             84 :         tdDefn = pg_strdup(copyBuf->data);
                               2873                 :                :     }
                               2874                 :                :     else
                               2875                 :           4412 :         copyFrom = fmtQualifiedDumpable(tbinfo);
                               2876                 :                : 
 1886 alvherre@alvh.no-ip.     2877         [ +  + ]:           4496 :     if (dopt->dump_inserts == 0)
                               2878                 :                :     {
                               2879                 :                :         /* Dump/restore using COPY */
 7945 tgl@sss.pgh.pa.us        2880                 :           4411 :         dumpFn = dumpTableData_copy;
                               2881                 :                :         /* must use 2 steps here 'cause fmtId is nonreentrant */
  904                          2882                 :           4411 :         printfPQExpBuffer(copyBuf, "COPY %s ",
                               2883                 :                :                           copyFrom);
 2482 andres@anarazel.de       2884                 :           4411 :         appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
                               2885                 :                :                           fmtCopyColumnList(tbinfo, clistBuf));
 7945 tgl@sss.pgh.pa.us        2886                 :           4411 :         copyStmt = copyBuf->data;
                               2887                 :                :     }
                               2888                 :                :     else
                               2889                 :                :     {
                               2890                 :                :         /* Restore using INSERT */
                               2891                 :             85 :         dumpFn = dumpTableData_insert;
                               2892                 :             85 :         copyStmt = NULL;
                               2893                 :                :     }
                               2894                 :                : 
                               2895                 :                :     /*
                               2896                 :                :      * Note: although the TableDataInfo is a full DumpableObject, we treat its
                               2897                 :                :      * dependency on its table as "special" and pass it to ArchiveEntry now.
                               2898                 :                :      * See comments for BuildArchiveDependencies.
                               2899                 :                :      */
 3440 sfrost@snowman.net       2900         [ +  - ]:           4496 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2901                 :                :     {
                               2902                 :                :         TocEntry   *te;
                               2903                 :                : 
 2549 tgl@sss.pgh.pa.us        2904                 :           4496 :         te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.     2905                 :           4496 :                           ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2906                 :                :                                        .namespace = tbinfo->dobj.namespace->dobj.name,
                               2907                 :                :                                        .owner = tbinfo->rolname,
                               2908                 :                :                                        .description = "TABLE DATA",
                               2909                 :                :                                        .section = SECTION_DATA,
                               2910                 :                :                                        .createStmt = tdDefn,
                               2911                 :                :                                        .copyStmt = copyStmt,
                               2912                 :                :                                        .deps = &(tbinfo->dobj.dumpId),
                               2913                 :                :                                        .nDeps = 1,
                               2914                 :                :                                        .dumpFn = dumpFn,
                               2915                 :                :                                        .dumpArg = tdinfo));
                               2916                 :                : 
                               2917                 :                :         /*
                               2918                 :                :          * Set the TocEntry's dataLength in case we are doing a parallel dump
                               2919                 :                :          * and want to order dump jobs by table size.  We choose to measure
                               2920                 :                :          * dataLength in table pages (including TOAST pages) during dump, so
                               2921                 :                :          * no scaling is needed.
                               2922                 :                :          *
                               2923                 :                :          * However, relpages is declared as "integer" in pg_class, and hence
                               2924                 :                :          * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
                               2925                 :                :          * Cast so that we get the right interpretation of table sizes
                               2926                 :                :          * exceeding INT_MAX pages.
                               2927                 :                :          */
 2549 tgl@sss.pgh.pa.us        2928                 :           4496 :         te->dataLength = (BlockNumber) tbinfo->relpages;
 1370                          2929                 :           4496 :         te->dataLength += (BlockNumber) tbinfo->toastpages;
                               2930                 :                : 
                               2931                 :                :         /*
                               2932                 :                :          * If pgoff_t is only 32 bits wide, the above refinement is useless,
                               2933                 :                :          * and instead we'd better worry about integer overflow.  Clamp to
                               2934                 :                :          * INT_MAX if the correct result exceeds that.
                               2935                 :                :          */
                               2936                 :                :         if (sizeof(te->dataLength) == 4 &&
                               2937                 :                :             (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
                               2938                 :                :              te->dataLength < 0))
                               2939                 :                :             te->dataLength = INT_MAX;
                               2940                 :                :     }
                               2941                 :                : 
 7945                          2942                 :           4496 :     destroyPQExpBuffer(copyBuf);
 4549 andrew@dunslane.net      2943                 :           4496 :     destroyPQExpBuffer(clistBuf);
 7945 tgl@sss.pgh.pa.us        2944                 :           4496 : }
                               2945                 :                : 
                               2946                 :                : /*
                               2947                 :                :  * refreshMatViewData -
                               2948                 :                :  *    load or refresh the contents of a single materialized view
                               2949                 :                :  *
                               2950                 :                :  * Actually, this just makes an ArchiveEntry for the REFRESH MATERIALIZED VIEW
                               2951                 :                :  * statement.
                               2952                 :                :  */
                               2953                 :                : static void
 1669 peter@eisentraut.org     2954                 :            432 : refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
                               2955                 :                : {
 4570 kgrittn@postgresql.o     2956                 :            432 :     TableInfo  *tbinfo = tdinfo->tdtable;
                               2957                 :                :     PQExpBuffer q;
                               2958                 :                : 
                               2959                 :                :     /* If the materialized view is not flagged as populated, skip this. */
 4506 tgl@sss.pgh.pa.us        2960         [ +  + ]:            432 :     if (!tbinfo->relispopulated)
 4570 kgrittn@postgresql.o     2961                 :             80 :         return;
                               2962                 :                : 
                               2963                 :            352 :     q = createPQExpBuffer();
                               2964                 :                : 
                               2965                 :            352 :     appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
 2749 tgl@sss.pgh.pa.us        2966                 :            352 :                       fmtQualifiedDumpable(tbinfo));
                               2967                 :                : 
 3440 sfrost@snowman.net       2968         [ +  - ]:            352 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2969                 :            352 :         ArchiveEntry(fout,
                               2970                 :                :                      tdinfo->dobj.catId, /* catalog ID */
 2999 tgl@sss.pgh.pa.us        2971                 :            352 :                      tdinfo->dobj.dumpId,    /* dump ID */
 2409 alvherre@alvh.no-ip.     2972                 :            352 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2973                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               2974                 :                :                                   .owner = tbinfo->rolname,
                               2975                 :                :                                   .description = "MATERIALIZED VIEW DATA",
                               2976                 :                :                                   .section = SECTION_POST_DATA,
                               2977                 :                :                                   .createStmt = q->data,
                               2978                 :                :                                   .deps = tdinfo->dobj.dependencies,
                               2979                 :                :                                   .nDeps = tdinfo->dobj.nDeps));
                               2980                 :                : 
 4570 kgrittn@postgresql.o     2981                 :            352 :     destroyPQExpBuffer(q);
                               2982                 :                : }
                               2983                 :                : 
                               2984                 :                : /*
                               2985                 :                :  * getTableData -
                               2986                 :                :  *    set up dumpable objects representing the contents of tables
                               2987                 :                :  */
                               2988                 :                : static void
 2482 andres@anarazel.de       2989                 :            177 : getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
                               2990                 :                : {
                               2991                 :                :     int         i;
                               2992                 :                : 
 8520 tgl@sss.pgh.pa.us        2993         [ +  + ]:          47317 :     for (i = 0; i < numTables; i++)
                               2994                 :                :     {
 3301 peter_e@gmx.net          2995   [ +  +  +  + ]:          47140 :         if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
                               2996         [ +  + ]:            929 :             (!relkind || tblinfo[i].relkind == relkind))
 2482 andres@anarazel.de       2997                 :           6296 :             makeTableDataInfo(dopt, &(tblinfo[i]));
                               2998                 :                :     }
 5324 tgl@sss.pgh.pa.us        2999                 :            177 : }
                               3000                 :                : 
                               3001                 :                : /*
                               3002                 :                :  * Make a dumpable object for the data of this specific table
                               3003                 :                :  *
                               3004                 :                :  * Note: we make a TableDataInfo if and only if we are going to dump the
                               3005                 :                :  * table data; the "dump" field in such objects isn't very interesting.
                               3006                 :                :  */
                               3007                 :                : static void
 2482 andres@anarazel.de       3008                 :           6407 : makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
                               3009                 :                : {
                               3010                 :                :     TableDataInfo *tdinfo;
                               3011                 :                : 
                               3012                 :                :     /*
                               3013                 :                :      * Nothing to do if we already decided to dump the table.  This will
                               3014                 :                :      * happen for "config" tables.
                               3015                 :                :      */
 4959 tgl@sss.pgh.pa.us        3016         [ +  + ]:           6407 :     if (tbinfo->dataObj != NULL)
                               3017                 :              1 :         return;
                               3018                 :                : 
                               3019                 :                :     /* Skip VIEWs (no data to dump) */
                               3020         [ +  + ]:           6406 :     if (tbinfo->relkind == RELKIND_VIEW)
                               3021                 :            487 :         return;
                               3022                 :                :     /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
 1991 alvherre@alvh.no-ip.     3023         [ +  + ]:           5919 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                               3024         [ +  + ]:             44 :         (foreign_servers_include_oids.head == NULL ||
 1941 tgl@sss.pgh.pa.us        3025         [ +  + ]:              4 :          !simple_oid_list_member(&foreign_servers_include_oids,
                               3026                 :                :                                  tbinfo->foreign_server)))
 4959                          3027                 :             43 :         return;
                               3028                 :                :     /* Skip partitioned tables (data in partitions) */
 3195 rhaas@postgresql.org     3029         [ +  + ]:           5876 :     if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
                               3030                 :            511 :         return;
                               3031                 :                : 
                               3032                 :                :     /* Don't dump data in unlogged tables, if so requested */
 4959 tgl@sss.pgh.pa.us        3033         [ +  + ]:           5365 :     if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
 3980 alvherre@alvh.no-ip.     3034         [ +  + ]:             41 :         dopt->no_unlogged_table_data)
 4959 tgl@sss.pgh.pa.us        3035                 :             18 :         return;
                               3036                 :                : 
                               3037                 :                :     /* Check that the data is not explicitly excluded */
                               3038         [ +  + ]:           5347 :     if (simple_oid_list_member(&tabledata_exclude_oids,
                               3039                 :                :                                tbinfo->dobj.catId.oid))
                               3040                 :              8 :         return;
                               3041                 :                : 
                               3042                 :                :     /* OK, let's dump it */
 5034 bruce@momjian.us         3043                 :           5339 :     tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
                               3044                 :                : 
 4570 kgrittn@postgresql.o     3045         [ +  + ]:           5339 :     if (tbinfo->relkind == RELKIND_MATVIEW)
                               3046                 :            432 :         tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
 3301 peter_e@gmx.net          3047         [ +  + ]:           4907 :     else if (tbinfo->relkind == RELKIND_SEQUENCE)
                               3048                 :            411 :         tdinfo->dobj.objType = DO_SEQUENCE_SET;
                               3049                 :                :     else
 4570 kgrittn@postgresql.o     3050                 :           4496 :         tdinfo->dobj.objType = DO_TABLE_DATA;
                               3051                 :                : 
                               3052                 :                :     /*
                               3053                 :                :      * Note: use tableoid 0 so that this object won't be mistaken for
                               3054                 :                :      * something that pg_depend entries apply to.
                               3055                 :                :      */
 5324 tgl@sss.pgh.pa.us        3056                 :           5339 :     tdinfo->dobj.catId.tableoid = 0;
                               3057                 :           5339 :     tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               3058                 :           5339 :     AssignDumpId(&tdinfo->dobj);
                               3059                 :           5339 :     tdinfo->dobj.name = tbinfo->dobj.name;
                               3060                 :           5339 :     tdinfo->dobj.namespace = tbinfo->dobj.namespace;
                               3061                 :           5339 :     tdinfo->tdtable = tbinfo;
 5263 bruce@momjian.us         3062                 :           5339 :     tdinfo->filtercond = NULL;   /* might get set later */
 5324 tgl@sss.pgh.pa.us        3063                 :           5339 :     addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
                               3064                 :                : 
                               3065                 :                :     /* A TableDataInfo contains data, of course */
 1370                          3066                 :           5339 :     tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               3067                 :                : 
 5324                          3068                 :           5339 :     tbinfo->dataObj = tdinfo;
                               3069                 :                : 
                               3070                 :                :     /*
                               3071                 :                :      * Materialized view statistics must be restored after the data, because
                               3072                 :                :      * REFRESH MATERIALIZED VIEW replaces the storage and resets the stats.
                               3073                 :                :      *
                               3074                 :                :      * The dependency is added here because the statistics objects are created
                               3075                 :                :      * first.
                               3076                 :                :      */
  162 jdavis@postgresql.or     3077   [ +  +  +  + ]:           5339 :     if (tbinfo->relkind == RELKIND_MATVIEW && tbinfo->stats != NULL)
                               3078                 :                :     {
                               3079                 :            350 :         tbinfo->stats->section = SECTION_POST_DATA;
                               3080                 :            350 :         addObjectDependency(&tbinfo->stats->dobj, tdinfo->dobj.dumpId);
                               3081                 :                :     }
                               3082                 :                : 
                               3083                 :                :     /* Make sure that we'll collect per-column info for this table. */
 1795 tgl@sss.pgh.pa.us        3084                 :           5339 :     tbinfo->interesting = true;
                               3085                 :                : }
                               3086                 :                : 
                               3087                 :                : /*
                               3088                 :                :  * The refresh for a materialized view must be dependent on the refresh for
                               3089                 :                :  * any materialized view that this one is dependent on.
                               3090                 :                :  *
                               3091                 :                :  * This must be called after all the objects are created, but before they are
                               3092                 :                :  * sorted.
                               3093                 :                :  */
                               3094                 :                : static void
 4570 kgrittn@postgresql.o     3095                 :            145 : buildMatViewRefreshDependencies(Archive *fout)
                               3096                 :                : {
                               3097                 :                :     PQExpBuffer query;
                               3098                 :                :     PGresult   *res;
                               3099                 :                :     int         ntups,
                               3100                 :                :                 i;
                               3101                 :                :     int         i_classid,
                               3102                 :                :                 i_objid,
                               3103                 :                :                 i_refobjid;
                               3104                 :                : 
                               3105                 :                :     /* No Mat Views before 9.3. */
 4560                          3106         [ -  + ]:            145 :     if (fout->remoteVersion < 90300)
 4560 kgrittn@postgresql.o     3107                 :UBC           0 :         return;
                               3108                 :                : 
 4560 kgrittn@postgresql.o     3109                 :CBC         145 :     query = createPQExpBuffer();
                               3110                 :                : 
 4310 heikki.linnakangas@i     3111                 :            145 :     appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
                               3112                 :                :                          "( "
                               3113                 :                :                          "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
                               3114                 :                :                          "FROM pg_depend d1 "
                               3115                 :                :                          "JOIN pg_class c1 ON c1.oid = d1.objid "
                               3116                 :                :                          "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
                               3117                 :                :                          " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
                               3118                 :                :                          "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
                               3119                 :                :                          "AND d2.objid = r1.oid "
                               3120                 :                :                          "AND d2.refobjid <> d1.objid "
                               3121                 :                :                          "JOIN pg_class c2 ON c2.oid = d2.refobjid "
                               3122                 :                :                          "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               3123                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               3124                 :                :                          "WHERE d1.classid = 'pg_class'::regclass "
                               3125                 :                :                          "UNION "
                               3126                 :                :                          "SELECT w.objid, d3.refobjid, c3.relkind "
                               3127                 :                :                          "FROM w "
                               3128                 :                :                          "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
                               3129                 :                :                          "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
                               3130                 :                :                          "AND d3.objid = r3.oid "
                               3131                 :                :                          "AND d3.refobjid <> w.refobjid "
                               3132                 :                :                          "JOIN pg_class c3 ON c3.oid = d3.refobjid "
                               3133                 :                :                          "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               3134                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               3135                 :                :                          ") "
                               3136                 :                :                          "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
                               3137                 :                :                          "FROM w "
                               3138                 :                :                          "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
                               3139                 :                : 
 4570 kgrittn@postgresql.o     3140                 :            145 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               3141                 :                : 
                               3142                 :            145 :     ntups = PQntuples(res);
                               3143                 :                : 
                               3144                 :            145 :     i_classid = PQfnumber(res, "classid");
                               3145                 :            145 :     i_objid = PQfnumber(res, "objid");
                               3146                 :            145 :     i_refobjid = PQfnumber(res, "refobjid");
                               3147                 :                : 
                               3148         [ +  + ]:            445 :     for (i = 0; i < ntups; i++)
                               3149                 :                :     {
                               3150                 :                :         CatalogId   objId;
                               3151                 :                :         CatalogId   refobjId;
                               3152                 :                :         DumpableObject *dobj;
                               3153                 :                :         DumpableObject *refdobj;
                               3154                 :                :         TableInfo  *tbinfo;
                               3155                 :                :         TableInfo  *reftbinfo;
                               3156                 :                : 
                               3157                 :            300 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                               3158                 :            300 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                               3159                 :            300 :         refobjId.tableoid = objId.tableoid;
                               3160                 :            300 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                               3161                 :                : 
                               3162                 :            300 :         dobj = findObjectByCatalogId(objId);
                               3163         [ -  + ]:            300 :         if (dobj == NULL)
                               3164                 :             48 :             continue;
                               3165                 :                : 
                               3166         [ -  + ]:            300 :         Assert(dobj->objType == DO_TABLE);
                               3167                 :            300 :         tbinfo = (TableInfo *) dobj;
                               3168         [ -  + ]:            300 :         Assert(tbinfo->relkind == RELKIND_MATVIEW);
                               3169                 :            300 :         dobj = (DumpableObject *) tbinfo->dataObj;
                               3170         [ +  + ]:            300 :         if (dobj == NULL)
                               3171                 :             48 :             continue;
                               3172         [ -  + ]:            252 :         Assert(dobj->objType == DO_REFRESH_MATVIEW);
                               3173                 :                : 
                               3174                 :            252 :         refdobj = findObjectByCatalogId(refobjId);
                               3175         [ -  + ]:            252 :         if (refdobj == NULL)
 4570 kgrittn@postgresql.o     3176                 :UBC           0 :             continue;
                               3177                 :                : 
 4570 kgrittn@postgresql.o     3178         [ -  + ]:CBC         252 :         Assert(refdobj->objType == DO_TABLE);
                               3179                 :            252 :         reftbinfo = (TableInfo *) refdobj;
                               3180         [ -  + ]:            252 :         Assert(reftbinfo->relkind == RELKIND_MATVIEW);
                               3181                 :            252 :         refdobj = (DumpableObject *) reftbinfo->dataObj;
                               3182         [ -  + ]:            252 :         if (refdobj == NULL)
 4570 kgrittn@postgresql.o     3183                 :UBC           0 :             continue;
 4570 kgrittn@postgresql.o     3184         [ -  + ]:CBC         252 :         Assert(refdobj->objType == DO_REFRESH_MATVIEW);
                               3185                 :                : 
                               3186                 :            252 :         addObjectDependency(dobj, refdobj->dumpId);
                               3187                 :                : 
 4506 tgl@sss.pgh.pa.us        3188         [ +  + ]:            252 :         if (!reftbinfo->relispopulated)
                               3189                 :             40 :             tbinfo->relispopulated = false;
                               3190                 :                :     }
                               3191                 :                : 
 4570 kgrittn@postgresql.o     3192                 :            145 :     PQclear(res);
                               3193                 :                : 
                               3194                 :            145 :     destroyPQExpBuffer(query);
                               3195                 :                : }
                               3196                 :                : 
                               3197                 :                : /*
                               3198                 :                :  * getTableDataFKConstraints -
                               3199                 :                :  *    add dump-order dependencies reflecting foreign key constraints
                               3200                 :                :  *
                               3201                 :                :  * This code is executed only in a data-only dump --- in schema+data dumps
                               3202                 :                :  * we handle foreign key issues by not creating the FK constraints until
                               3203                 :                :  * after the data is loaded.  In a data-only dump, however, we want to
                               3204                 :                :  * order the table data objects in such a way that a table's referenced
                               3205                 :                :  * tables are restored first.  (In the presence of circular references or
                               3206                 :                :  * self-references this may be impossible; we'll detect and complain about
                               3207                 :                :  * that during the dependency sorting step.)
                               3208                 :                :  */
                               3209                 :                : static void
 6207 tgl@sss.pgh.pa.us        3210                 :              7 : getTableDataFKConstraints(void)
                               3211                 :                : {
                               3212                 :                :     DumpableObject **dobjs;
                               3213                 :                :     int         numObjs;
                               3214                 :                :     int         i;
                               3215                 :                : 
                               3216                 :                :     /* Search through all the dumpable objects for FK constraints */
                               3217                 :              7 :     getDumpableObjects(&dobjs, &numObjs);
                               3218         [ +  + ]:          30721 :     for (i = 0; i < numObjs; i++)
                               3219                 :                :     {
                               3220         [ +  + ]:          30714 :         if (dobjs[i]->objType == DO_FK_CONSTRAINT)
                               3221                 :                :         {
                               3222                 :              8 :             ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
                               3223                 :                :             TableInfo  *ftable;
                               3224                 :                : 
                               3225                 :                :             /* Not interesting unless both tables are to be dumped */
                               3226         [ +  - ]:              8 :             if (cinfo->contable == NULL ||
                               3227         [ +  + ]:              8 :                 cinfo->contable->dataObj == NULL)
                               3228                 :              4 :                 continue;
                               3229                 :              4 :             ftable = findTableByOid(cinfo->confrelid);
                               3230         [ +  - ]:              4 :             if (ftable == NULL ||
                               3231         [ -  + ]:              4 :                 ftable->dataObj == NULL)
 6207 tgl@sss.pgh.pa.us        3232                 :UBC           0 :                 continue;
                               3233                 :                : 
                               3234                 :                :             /*
                               3235                 :                :              * Okay, make referencing table's TABLE_DATA object depend on the
                               3236                 :                :              * referenced table's TABLE_DATA object.
                               3237                 :                :              */
 6207 tgl@sss.pgh.pa.us        3238                 :CBC           4 :             addObjectDependency(&cinfo->contable->dataObj->dobj,
                               3239                 :              4 :                                 ftable->dataObj->dobj.dumpId);
                               3240                 :                :         }
                               3241                 :                :     }
                               3242                 :              7 :     free(dobjs);
                               3243                 :              7 : }
                               3244                 :                : 
                               3245                 :                : 
                               3246                 :                : /*
                               3247                 :                :  * dumpDatabase:
                               3248                 :                :  *  dump the database definition
                               3249                 :                :  */
                               3250                 :                : static void
 3524                          3251                 :             84 : dumpDatabase(Archive *fout)
                               3252                 :                : {
                               3253                 :             84 :     DumpOptions *dopt = fout->dopt;
 8934 bruce@momjian.us         3254                 :             84 :     PQExpBuffer dbQry = createPQExpBuffer();
                               3255                 :             84 :     PQExpBuffer delQry = createPQExpBuffer();
                               3256                 :             84 :     PQExpBuffer creaQry = createPQExpBuffer();
 2784 tgl@sss.pgh.pa.us        3257                 :             84 :     PQExpBuffer labelq = createPQExpBuffer();
 4951 rhaas@postgresql.org     3258                 :             84 :     PGconn     *conn = GetConnection(fout);
                               3259                 :                :     PGresult   *res;
                               3260                 :                :     int         i_tableoid,
                               3261                 :                :                 i_oid,
                               3262                 :                :                 i_datname,
                               3263                 :                :                 i_datdba,
                               3264                 :                :                 i_encoding,
                               3265                 :                :                 i_datlocprovider,
                               3266                 :                :                 i_collate,
                               3267                 :                :                 i_ctype,
                               3268                 :                :                 i_datlocale,
                               3269                 :                :                 i_daticurules,
                               3270                 :                :                 i_frozenxid,
                               3271                 :                :                 i_minmxid,
                               3272                 :                :                 i_datacl,
                               3273                 :                :                 i_acldefault,
                               3274                 :                :                 i_datistemplate,
                               3275                 :                :                 i_datconnlimit,
                               3276                 :                :                 i_datcollversion,
                               3277                 :                :                 i_tablespace;
                               3278                 :                :     CatalogId   dbCatId;
                               3279                 :                :     DumpId      dbDumpId;
                               3280                 :                :     DumpableAcl dbdacl;
                               3281                 :                :     const char *datname,
                               3282                 :                :                *dba,
                               3283                 :                :                *encoding,
                               3284                 :                :                *datlocprovider,
                               3285                 :                :                *collate,
                               3286                 :                :                *ctype,
                               3287                 :                :                *locale,
                               3288                 :                :                *icurules,
                               3289                 :                :                *datistemplate,
                               3290                 :                :                *datconnlimit,
                               3291                 :                :                *tablespace;
                               3292                 :                :     uint32      frozenxid,
                               3293                 :                :                 minmxid;
                               3294                 :                :     char       *qdatname;
                               3295                 :                : 
 2350 peter@eisentraut.org     3296                 :             84 :     pg_log_info("saving database definition");
                               3297                 :                : 
                               3298                 :                :     /*
                               3299                 :                :      * Fetch the database-level properties for this database.
                               3300                 :                :      */
 1096 drowley@postgresql.o     3301                 :             84 :     appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
                               3302                 :                :                          "datdba, "
                               3303                 :                :                          "pg_encoding_to_char(encoding) AS encoding, "
                               3304                 :                :                          "datcollate, datctype, datfrozenxid, "
                               3305                 :                :                          "datacl, acldefault('d', datdba) AS acldefault, "
                               3306                 :                :                          "datistemplate, datconnlimit, ");
 1370 tgl@sss.pgh.pa.us        3307         [ +  - ]:             84 :     if (fout->remoteVersion >= 90300)
 1096 drowley@postgresql.o     3308                 :             84 :         appendPQExpBufferStr(dbQry, "datminmxid, ");
                               3309                 :                :     else
 1096 drowley@postgresql.o     3310                 :UBC           0 :         appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
  546 jdavis@postgresql.or     3311         [ +  - ]:CBC          84 :     if (fout->remoteVersion >= 170000)
                               3312                 :             84 :         appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
  546 jdavis@postgresql.or     3313         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 150000)
                               3314                 :              0 :         appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
                               3315                 :                :     else
                               3316                 :              0 :         appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
  913 peter@eisentraut.org     3317         [ +  - ]:CBC          84 :     if (fout->remoteVersion >= 160000)
                               3318                 :             84 :         appendPQExpBufferStr(dbQry, "daticurules, ");
                               3319                 :                :     else
  913 peter@eisentraut.org     3320                 :UBC           0 :         appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
 1096 drowley@postgresql.o     3321                 :CBC          84 :     appendPQExpBufferStr(dbQry,
                               3322                 :                :                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                               3323                 :                :                          "shobj_description(oid, 'pg_database') AS description "
                               3324                 :                :                          "FROM pg_database "
                               3325                 :                :                          "WHERE datname = current_database()");
                               3326                 :                : 
 4951 rhaas@postgresql.org     3327                 :             84 :     res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
                               3328                 :                : 
 7945 tgl@sss.pgh.pa.us        3329                 :             84 :     i_tableoid = PQfnumber(res, "tableoid");
                               3330                 :             84 :     i_oid = PQfnumber(res, "oid");
 2706 peter_e@gmx.net          3331                 :             84 :     i_datname = PQfnumber(res, "datname");
 1345 tgl@sss.pgh.pa.us        3332                 :             84 :     i_datdba = PQfnumber(res, "datdba");
 8608                          3333                 :             84 :     i_encoding = PQfnumber(res, "encoding");
 1269 peter@eisentraut.org     3334                 :             84 :     i_datlocprovider = PQfnumber(res, "datlocprovider");
 6191 heikki.linnakangas@i     3335                 :             84 :     i_collate = PQfnumber(res, "datcollate");
                               3336                 :             84 :     i_ctype = PQfnumber(res, "datctype");
  546 jdavis@postgresql.or     3337                 :             84 :     i_datlocale = PQfnumber(res, "datlocale");
  913 peter@eisentraut.org     3338                 :             84 :     i_daticurules = PQfnumber(res, "daticurules");
 6044 bruce@momjian.us         3339                 :             84 :     i_frozenxid = PQfnumber(res, "datfrozenxid");
 4084                          3340                 :             84 :     i_minmxid = PQfnumber(res, "datminmxid");
 2784 tgl@sss.pgh.pa.us        3341                 :             84 :     i_datacl = PQfnumber(res, "datacl");
 1370                          3342                 :             84 :     i_acldefault = PQfnumber(res, "acldefault");
 2784                          3343                 :             84 :     i_datistemplate = PQfnumber(res, "datistemplate");
                               3344                 :             84 :     i_datconnlimit = PQfnumber(res, "datconnlimit");
 1300 peter@eisentraut.org     3345                 :             84 :     i_datcollversion = PQfnumber(res, "datcollversion");
 7750 tgl@sss.pgh.pa.us        3346                 :             84 :     i_tablespace = PQfnumber(res, "tablespace");
                               3347                 :                : 
 7945                          3348                 :             84 :     dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
                               3349                 :             84 :     dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
 2706 peter_e@gmx.net          3350                 :             84 :     datname = PQgetvalue(res, 0, i_datname);
 1345 tgl@sss.pgh.pa.us        3351                 :             84 :     dba = getRoleName(PQgetvalue(res, 0, i_datdba));
 8608                          3352                 :             84 :     encoding = PQgetvalue(res, 0, i_encoding);
 1269 peter@eisentraut.org     3353                 :             84 :     datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
 6192 heikki.linnakangas@i     3354                 :             84 :     collate = PQgetvalue(res, 0, i_collate);
                               3355                 :             84 :     ctype = PQgetvalue(res, 0, i_ctype);
  546 jdavis@postgresql.or     3356         [ +  + ]:             84 :     if (!PQgetisnull(res, 0, i_datlocale))
                               3357                 :             14 :         locale = PQgetvalue(res, 0, i_datlocale);
                               3358                 :                :     else
                               3359                 :             70 :         locale = NULL;
  913 peter@eisentraut.org     3360         [ -  + ]:             84 :     if (!PQgetisnull(res, 0, i_daticurules))
  913 peter@eisentraut.org     3361                 :UBC           0 :         icurules = PQgetvalue(res, 0, i_daticurules);
                               3362                 :                :     else
  913 peter@eisentraut.org     3363                 :CBC          84 :         icurules = NULL;
 6044 bruce@momjian.us         3364                 :             84 :     frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
 4084                          3365                 :             84 :     minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
 1370 tgl@sss.pgh.pa.us        3366                 :             84 :     dbdacl.acl = PQgetvalue(res, 0, i_datacl);
                               3367                 :             84 :     dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
 2784                          3368                 :             84 :     datistemplate = PQgetvalue(res, 0, i_datistemplate);
                               3369                 :             84 :     datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
 7750                          3370                 :             84 :     tablespace = PQgetvalue(res, 0, i_tablespace);
                               3371                 :                : 
 2706 peter_e@gmx.net          3372                 :             84 :     qdatname = pg_strdup(fmtId(datname));
                               3373                 :                : 
                               3374                 :                :     /*
                               3375                 :                :      * Prepare the CREATE DATABASE command.  We must specify OID (if we want
                               3376                 :                :      * to preserve that), as well as the encoding, locale, and tablespace
                               3377                 :                :      * since those can't be altered later.  Other DB properties are left to
                               3378                 :                :      * the DATABASE PROPERTIES entry, so that they can be applied after
                               3379                 :                :      * reconnecting to the target DB.
                               3380                 :                :      *
                               3381                 :                :      * For binary upgrade, we use the FILE_COPY strategy because testing has
                               3382                 :                :      * shown it to be faster.  When the server is in binary upgrade mode, it
                               3383                 :                :      * will also skip the checkpoints this strategy ordinarily performs.
                               3384                 :                :      */
 1321 rhaas@postgresql.org     3385         [ +  + ]:             84 :     if (dopt->binary_upgrade)
                               3386                 :                :     {
  425 nathan@postgresql.or     3387                 :             35 :         appendPQExpBuffer(creaQry,
                               3388                 :                :                           "CREATE DATABASE %s WITH TEMPLATE = template0 "
                               3389                 :                :                           "OID = %u STRATEGY = FILE_COPY",
                               3390                 :                :                           qdatname, dbCatId.oid);
                               3391                 :                :     }
                               3392                 :                :     else
                               3393                 :                :     {
 1321 rhaas@postgresql.org     3394                 :             49 :         appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
                               3395                 :                :                           qdatname);
                               3396                 :                :     }
 8295 tgl@sss.pgh.pa.us        3397         [ +  - ]:             84 :     if (strlen(encoding) > 0)
                               3398                 :                :     {
 4310 heikki.linnakangas@i     3399                 :             84 :         appendPQExpBufferStr(creaQry, " ENCODING = ");
 4961 rhaas@postgresql.org     3400                 :             84 :         appendStringLiteralAH(creaQry, encoding, fout);
                               3401                 :                :     }
                               3402                 :                : 
 1269 peter@eisentraut.org     3403                 :             84 :     appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
  542 jdavis@postgresql.or     3404         [ +  + ]:             84 :     if (datlocprovider[0] == 'b')
                               3405                 :             14 :         appendPQExpBufferStr(creaQry, "builtin");
                               3406         [ +  - ]:             70 :     else if (datlocprovider[0] == 'c')
 1269 peter@eisentraut.org     3407                 :             70 :         appendPQExpBufferStr(creaQry, "libc");
 1269 peter@eisentraut.org     3408         [ #  # ]:UBC           0 :     else if (datlocprovider[0] == 'i')
                               3409                 :              0 :         appendPQExpBufferStr(creaQry, "icu");
                               3410                 :                :     else
 1247 tgl@sss.pgh.pa.us        3411                 :              0 :         pg_fatal("unrecognized locale provider: %s",
                               3412                 :                :                  datlocprovider);
                               3413                 :                : 
 2237 peter@eisentraut.org     3414   [ +  -  +  - ]:CBC          84 :     if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
                               3415                 :                :     {
                               3416                 :             84 :         appendPQExpBufferStr(creaQry, " LOCALE = ");
 4961 rhaas@postgresql.org     3417                 :             84 :         appendStringLiteralAH(creaQry, collate, fout);
                               3418                 :                :     }
                               3419                 :                :     else
                               3420                 :                :     {
 2237 peter@eisentraut.org     3421         [ #  # ]:UBC           0 :         if (strlen(collate) > 0)
                               3422                 :                :         {
                               3423                 :              0 :             appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
                               3424                 :              0 :             appendStringLiteralAH(creaQry, collate, fout);
                               3425                 :                :         }
                               3426         [ #  # ]:              0 :         if (strlen(ctype) > 0)
                               3427                 :                :         {
                               3428                 :              0 :             appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
                               3429                 :              0 :             appendStringLiteralAH(creaQry, ctype, fout);
                               3430                 :                :         }
                               3431                 :                :     }
  546 jdavis@postgresql.or     3432         [ +  + ]:CBC          84 :     if (locale)
                               3433                 :                :     {
  542                          3434         [ +  - ]:             14 :         if (datlocprovider[0] == 'b')
                               3435                 :             14 :             appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
                               3436                 :                :         else
  542 jdavis@postgresql.or     3437                 :UBC           0 :             appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
                               3438                 :                : 
  546 jdavis@postgresql.or     3439                 :CBC          14 :         appendStringLiteralAH(creaQry, locale, fout);
                               3440                 :                :     }
                               3441                 :                : 
  913 peter@eisentraut.org     3442         [ -  + ]:             84 :     if (icurules)
                               3443                 :                :     {
  913 peter@eisentraut.org     3444                 :UBC           0 :         appendPQExpBufferStr(creaQry, " ICU_RULES = ");
                               3445                 :              0 :         appendStringLiteralAH(creaQry, icurules, fout);
                               3446                 :                :     }
                               3447                 :                : 
                               3448                 :                :     /*
                               3449                 :                :      * For binary upgrade, carry over the collation version.  For normal
                               3450                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                               3451                 :                :      */
 1300 peter@eisentraut.org     3452         [ +  + ]:CBC          84 :     if (dopt->binary_upgrade)
                               3453                 :                :     {
                               3454         [ +  + ]:             35 :         if (!PQgetisnull(res, 0, i_datcollversion))
                               3455                 :                :         {
                               3456                 :              6 :             appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
                               3457                 :              6 :             appendStringLiteralAH(creaQry,
                               3458                 :                :                                   PQgetvalue(res, 0, i_datcollversion),
                               3459                 :                :                                   fout);
                               3460                 :                :         }
                               3461                 :                :     }
                               3462                 :                : 
                               3463                 :                :     /*
                               3464                 :                :      * Note: looking at dopt->outputNoTablespaces here is completely the wrong
                               3465                 :                :      * thing; the decision whether to specify a tablespace should be left till
                               3466                 :                :      * pg_restore, so that pg_restore --no-tablespaces applies.  Ideally we'd
                               3467                 :                :      * label the DATABASE entry with the tablespace and let the normal
                               3468                 :                :      * tablespace selection logic work ... but CREATE DATABASE doesn't pay
                               3469                 :                :      * attention to default_tablespace, so that won't work.
                               3470                 :                :      */
 3285 tgl@sss.pgh.pa.us        3471   [ +  -  +  + ]:             84 :     if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
 3285 tgl@sss.pgh.pa.us        3472         [ +  - ]:GBC           5 :         !dopt->outputNoTablespaces)
 7628                          3473                 :              5 :         appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                               3474                 :                :                           fmtId(tablespace));
 4310 heikki.linnakangas@i     3475                 :CBC          84 :     appendPQExpBufferStr(creaQry, ";\n");
                               3476                 :                : 
 8608 tgl@sss.pgh.pa.us        3477                 :             84 :     appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
                               3478                 :                :                       qdatname);
                               3479                 :                : 
 7945                          3480                 :             84 :     dbDumpId = createDumpId();
                               3481                 :                : 
 4961 rhaas@postgresql.org     3482                 :             84 :     ArchiveEntry(fout,
                               3483                 :                :                  dbCatId,       /* catalog ID */
                               3484                 :                :                  dbDumpId,      /* dump ID */
 2409 alvherre@alvh.no-ip.     3485                 :             84 :                  ARCHIVE_OPTS(.tag = datname,
                               3486                 :                :                               .owner = dba,
                               3487                 :                :                               .description = "DATABASE",
                               3488                 :                :                               .section = SECTION_PRE_DATA,
                               3489                 :                :                               .createStmt = creaQry->data,
                               3490                 :                :                               .dropStmt = delQry->data));
                               3491                 :                : 
                               3492                 :                :     /* Compute correct tag for archive entry */
 2784 tgl@sss.pgh.pa.us        3493                 :             84 :     appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
                               3494                 :                : 
                               3495                 :                :     /* Dump DB comment if any */
                               3496                 :                :     {
                               3497                 :                :         /*
                               3498                 :                :          * 8.2 and up keep comments on shared objects in a shared table, so we
                               3499                 :                :          * cannot use the dumpComment() code used for other database objects.
                               3500                 :                :          * Be careful that the ArchiveEntry parameters match that function.
                               3501                 :                :          */
                               3502                 :             84 :         char       *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
                               3503                 :                : 
 2781                          3504   [ +  -  +  +  :             84 :         if (comment && *comment && !dopt->no_comments)
                                              +  - ]
                               3505                 :                :         {
 2784                          3506                 :             39 :             resetPQExpBuffer(dbQry);
                               3507                 :                : 
                               3508                 :                :             /*
                               3509                 :                :              * Generates warning when loaded into a differently-named
                               3510                 :                :              * database.
                               3511                 :                :              */
                               3512                 :             39 :             appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
                               3513                 :             39 :             appendStringLiteralAH(dbQry, comment, fout);
                               3514                 :             39 :             appendPQExpBufferStr(dbQry, ";\n");
                               3515                 :                : 
                               3516                 :             39 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3517                 :             39 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3518                 :                :                                       .owner = dba,
                               3519                 :                :                                       .description = "COMMENT",
                               3520                 :                :                                       .section = SECTION_NONE,
                               3521                 :                :                                       .createStmt = dbQry->data,
                               3522                 :                :                                       .deps = &dbDumpId,
                               3523                 :                :                                       .nDeps = 1));
                               3524                 :                :         }
                               3525                 :                :     }
                               3526                 :                : 
                               3527                 :                :     /* Dump DB security label, if enabled */
 1362 tgl@sss.pgh.pa.us        3528         [ +  - ]:             84 :     if (!dopt->no_security_labels)
                               3529                 :                :     {
                               3530                 :                :         PGresult   *shres;
                               3531                 :                :         PQExpBuffer seclabelQry;
                               3532                 :                : 
 2784                          3533                 :             84 :         seclabelQry = createPQExpBuffer();
                               3534                 :                : 
 1838 peter@eisentraut.org     3535                 :             84 :         buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
 2784 tgl@sss.pgh.pa.us        3536                 :             84 :         shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
                               3537                 :             84 :         resetPQExpBuffer(seclabelQry);
                               3538                 :             84 :         emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
                               3539         [ -  + ]:             84 :         if (seclabelQry->len > 0)
 2784 tgl@sss.pgh.pa.us        3540                 :UBC           0 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3541                 :              0 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3542                 :                :                                       .owner = dba,
                               3543                 :                :                                       .description = "SECURITY LABEL",
                               3544                 :                :                                       .section = SECTION_NONE,
                               3545                 :                :                                       .createStmt = seclabelQry->data,
                               3546                 :                :                                       .deps = &dbDumpId,
                               3547                 :                :                                       .nDeps = 1));
 2784 tgl@sss.pgh.pa.us        3548                 :CBC          84 :         destroyPQExpBuffer(seclabelQry);
                               3549                 :             84 :         PQclear(shres);
                               3550                 :                :     }
                               3551                 :                : 
                               3552                 :                :     /*
                               3553                 :                :      * Dump ACL if any.  Note that we do not support initial privileges
                               3554                 :                :      * (pg_init_privs) on databases.
                               3555                 :                :      */
 1370                          3556                 :             84 :     dbdacl.privtype = 0;
                               3557                 :             84 :     dbdacl.initprivs = NULL;
                               3558                 :                : 
 1883                          3559                 :             84 :     dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
                               3560                 :                :             qdatname, NULL, NULL,
                               3561                 :                :             NULL, dba, &dbdacl);
                               3562                 :                : 
                               3563                 :                :     /*
                               3564                 :                :      * Now construct a DATABASE PROPERTIES archive entry to restore any
                               3565                 :                :      * non-default database-level properties.  (The reason this must be
                               3566                 :                :      * separate is that we cannot put any additional commands into the TOC
                               3567                 :                :      * entry that has CREATE DATABASE.  pg_restore would execute such a group
                               3568                 :                :      * in an implicit transaction block, and the backend won't allow CREATE
                               3569                 :                :      * DATABASE in that context.)
                               3570                 :                :      */
 2784                          3571                 :             84 :     resetPQExpBuffer(creaQry);
                               3572                 :             84 :     resetPQExpBuffer(delQry);
                               3573                 :                : 
                               3574   [ +  -  -  + ]:             84 :     if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
 2784 tgl@sss.pgh.pa.us        3575                 :UBC           0 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
                               3576                 :                :                           qdatname, datconnlimit);
                               3577                 :                : 
 2784 tgl@sss.pgh.pa.us        3578         [ +  + ]:CBC          84 :     if (strcmp(datistemplate, "t") == 0)
                               3579                 :                :     {
                               3580                 :             10 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
                               3581                 :                :                           qdatname);
                               3582                 :                : 
                               3583                 :                :         /*
                               3584                 :                :          * The backend won't accept DROP DATABASE on a template database.  We
                               3585                 :                :          * can deal with that by removing the template marking before the DROP
                               3586                 :                :          * gets issued.  We'd prefer to use ALTER DATABASE IF EXISTS here, but
                               3587                 :                :          * since no such command is currently supported, fake it with a direct
                               3588                 :                :          * UPDATE on pg_database.
                               3589                 :                :          */
                               3590                 :             10 :         appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
                               3591                 :                :                              "SET datistemplate = false WHERE datname = ");
                               3592                 :             10 :         appendStringLiteralAH(delQry, datname, fout);
                               3593                 :             10 :         appendPQExpBufferStr(delQry, ";\n");
                               3594                 :                :     }
                               3595                 :                : 
                               3596                 :                :     /*
                               3597                 :                :      * We do not restore pg_database.dathasloginevt because it is set
                               3598                 :                :      * automatically on login event trigger creation.
                               3599                 :                :      */
                               3600                 :                : 
                               3601                 :                :     /* Add database-specific SET options */
                               3602                 :             84 :     dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
                               3603                 :                : 
                               3604                 :                :     /*
                               3605                 :                :      * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
                               3606                 :                :      * entry, too, for lack of a better place.
                               3607                 :                :      */
                               3608         [ +  + ]:             84 :     if (dopt->binary_upgrade)
                               3609                 :                :     {
                               3610                 :             35 :         appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
                               3611                 :             35 :         appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
                               3612                 :                :                           "SET datfrozenxid = '%u', datminmxid = '%u'\n"
                               3613                 :                :                           "WHERE datname = ",
                               3614                 :                :                           frozenxid, minmxid);
                               3615                 :             35 :         appendStringLiteralAH(creaQry, datname, fout);
                               3616                 :             35 :         appendPQExpBufferStr(creaQry, ";\n");
                               3617                 :                :     }
                               3618                 :                : 
                               3619         [ +  + ]:             84 :     if (creaQry->len > 0)
                               3620                 :             39 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3621                 :             39 :                      ARCHIVE_OPTS(.tag = datname,
                               3622                 :                :                                   .owner = dba,
                               3623                 :                :                                   .description = "DATABASE PROPERTIES",
                               3624                 :                :                                   .section = SECTION_PRE_DATA,
                               3625                 :                :                                   .createStmt = creaQry->data,
                               3626                 :                :                                   .dropStmt = delQry->data,
                               3627                 :                :                                   .deps = &dbDumpId));
                               3628                 :                : 
                               3629                 :                :     /*
                               3630                 :                :      * pg_largeobject comes from the old system intact, so set its
                               3631                 :                :      * relfrozenxids, relminmxids and relfilenode.
                               3632                 :                :      */
 3980                          3633         [ +  + ]:             84 :     if (dopt->binary_upgrade)
                               3634                 :                :     {
                               3635                 :                :         PGresult   *lo_res;
 5892 bruce@momjian.us         3636                 :             35 :         PQExpBuffer loFrozenQry = createPQExpBuffer();
                               3637                 :             35 :         PQExpBuffer loOutQry = createPQExpBuffer();
 1135 rhaas@postgresql.org     3638                 :             35 :         PQExpBuffer loHorizonQry = createPQExpBuffer();
                               3639                 :                :         int         ii_relfrozenxid,
                               3640                 :                :                     ii_relfilenode,
                               3641                 :                :                     ii_oid,
                               3642                 :                :                     ii_relminmxid;
                               3643                 :                : 
                               3644                 :                :         /*
                               3645                 :                :          * pg_largeobject
                               3646                 :                :          */
 4084 bruce@momjian.us         3647         [ +  - ]:             35 :         if (fout->remoteVersion >= 90300)
 1156 rhaas@postgresql.org     3648                 :             35 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
                               3649                 :                :                               "FROM pg_catalog.pg_class\n"
                               3650                 :                :                               "WHERE oid IN (%u, %u);\n",
                               3651                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId);
                               3652                 :                :         else
 1156 rhaas@postgresql.org     3653                 :UBC           0 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
                               3654                 :                :                               "FROM pg_catalog.pg_class\n"
                               3655                 :                :                               "WHERE oid IN (%u, %u);\n",
                               3656                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId);
                               3657                 :                : 
 1156 rhaas@postgresql.org     3658                 :CBC          35 :         lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
                               3659                 :                : 
 1113 drowley@postgresql.o     3660                 :             35 :         ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
                               3661                 :             35 :         ii_relminmxid = PQfnumber(lo_res, "relminmxid");
                               3662                 :             35 :         ii_relfilenode = PQfnumber(lo_res, "relfilenode");
                               3663                 :             35 :         ii_oid = PQfnumber(lo_res, "oid");
                               3664                 :                : 
 1135 rhaas@postgresql.org     3665                 :             35 :         appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
                               3666                 :             35 :         appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
 1156                          3667         [ +  + ]:            105 :         for (int i = 0; i < PQntuples(lo_res); ++i)
                               3668                 :                :         {
                               3669                 :                :             Oid         oid;
                               3670                 :                :             RelFileNumber relfilenumber;
                               3671                 :                : 
 1135                          3672                 :             70 :             appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
                               3673                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                               3674                 :                :                               "WHERE oid = %u;\n",
 1113 drowley@postgresql.o     3675                 :             70 :                               atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
                               3676                 :             70 :                               atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
                               3677                 :             70 :                               atooid(PQgetvalue(lo_res, i, ii_oid)));
                               3678                 :                : 
                               3679                 :             70 :             oid = atooid(PQgetvalue(lo_res, i, ii_oid));
 1074 rhaas@postgresql.org     3680                 :             70 :             relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
                               3681                 :                : 
 1136                          3682         [ +  + ]:             70 :             if (oid == LargeObjectRelationId)
 1135                          3683                 :             35 :                 appendPQExpBuffer(loOutQry,
                               3684                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               3685                 :                :                                   relfilenumber);
 1136                          3686         [ +  - ]:             35 :             else if (oid == LargeObjectLOidPNIndexId)
 1135                          3687                 :             35 :                 appendPQExpBuffer(loOutQry,
                               3688                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               3689                 :                :                                   relfilenumber);
                               3690                 :                :         }
                               3691                 :                : 
                               3692                 :             35 :         appendPQExpBufferStr(loOutQry,
                               3693                 :                :                              "TRUNCATE pg_catalog.pg_largeobject;\n");
                               3694                 :             35 :         appendPQExpBufferStr(loOutQry, loHorizonQry->data);
                               3695                 :                : 
 4961                          3696                 :             35 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3697                 :             35 :                      ARCHIVE_OPTS(.tag = "pg_largeobject",
                               3698                 :                :                                   .description = "pg_largeobject",
                               3699                 :                :                                   .section = SECTION_PRE_DATA,
                               3700                 :                :                                   .createStmt = loOutQry->data));
                               3701                 :                : 
 5892 bruce@momjian.us         3702                 :             35 :         PQclear(lo_res);
                               3703                 :                : 
                               3704                 :             35 :         destroyPQExpBuffer(loFrozenQry);
 1135 rhaas@postgresql.org     3705                 :             35 :         destroyPQExpBuffer(loHorizonQry);
 5892 bruce@momjian.us         3706                 :             35 :         destroyPQExpBuffer(loOutQry);
                               3707                 :                :     }
                               3708                 :                : 
 3884 andres@anarazel.de       3709                 :             84 :     PQclear(res);
                               3710                 :                : 
 2784 tgl@sss.pgh.pa.us        3711                 :             84 :     free(qdatname);
 8800                          3712                 :             84 :     destroyPQExpBuffer(dbQry);
                               3713                 :             84 :     destroyPQExpBuffer(delQry);
                               3714                 :             84 :     destroyPQExpBuffer(creaQry);
 2784                          3715                 :             84 :     destroyPQExpBuffer(labelq);
 9167 pjw@rhyme.com.au         3716                 :             84 : }
                               3717                 :                : 
                               3718                 :                : /*
                               3719                 :                :  * Collect any database-specific or role-and-database-specific SET options
                               3720                 :                :  * for this database, and append them to outbuf.
                               3721                 :                :  */
                               3722                 :                : static void
 2784 tgl@sss.pgh.pa.us        3723                 :             84 : dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                               3724                 :                :                    const char *dbname, Oid dboid)
                               3725                 :                : {
                               3726                 :             84 :     PGconn     *conn = GetConnection(AH);
                               3727                 :             84 :     PQExpBuffer buf = createPQExpBuffer();
                               3728                 :                :     PGresult   *res;
                               3729                 :                : 
                               3730                 :                :     /* First collect database-specific options */
  843 akorotkov@postgresql     3731                 :             84 :     printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
                               3732                 :                :                       "WHERE setrole = 0 AND setdatabase = '%u'::oid",
                               3733                 :                :                       dboid);
                               3734                 :                : 
 1362 tgl@sss.pgh.pa.us        3735                 :             84 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3736                 :                : 
                               3737         [ +  + ]:            114 :     for (int i = 0; i < PQntuples(res); i++)
  843 akorotkov@postgresql     3738                 :             30 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
                               3739                 :                :                                "DATABASE", dbname, NULL, NULL,
                               3740                 :                :                                outbuf);
                               3741                 :                : 
 1362 tgl@sss.pgh.pa.us        3742                 :             84 :     PQclear(res);
                               3743                 :                : 
                               3744                 :                :     /* Now look for role-and-database-specific options */
  843 akorotkov@postgresql     3745                 :             84 :     printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
                               3746                 :                :                       "FROM pg_db_role_setting s, pg_roles r "
                               3747                 :                :                       "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
                               3748                 :                :                       dboid);
                               3749                 :                : 
 1362 tgl@sss.pgh.pa.us        3750                 :             84 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3751                 :                : 
                               3752         [ -  + ]:             84 :     for (int i = 0; i < PQntuples(res); i++)
  843 akorotkov@postgresql     3753                 :UBC           0 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 1),
 1362 tgl@sss.pgh.pa.us        3754                 :              0 :                                "ROLE", PQgetvalue(res, i, 0),
                               3755                 :                :                                "DATABASE", dbname,
                               3756                 :                :                                outbuf);
                               3757                 :                : 
 1362 tgl@sss.pgh.pa.us        3758                 :CBC          84 :     PQclear(res);
                               3759                 :                : 
 2784                          3760                 :             84 :     destroyPQExpBuffer(buf);
                               3761                 :             84 : }
                               3762                 :                : 
                               3763                 :                : /*
                               3764                 :                :  * dumpEncoding: put the correct encoding into the archive
                               3765                 :                :  */
                               3766                 :                : static void
 7865                          3767                 :            185 : dumpEncoding(Archive *AH)
                               3768                 :                : {
 7041                          3769                 :            185 :     const char *encname = pg_encoding_to_char(AH->encoding);
                               3770                 :            185 :     PQExpBuffer qry = createPQExpBuffer();
                               3771                 :                : 
 2350 peter@eisentraut.org     3772                 :            185 :     pg_log_info("saving encoding = %s", encname);
                               3773                 :                : 
 4310 heikki.linnakangas@i     3774                 :            185 :     appendPQExpBufferStr(qry, "SET client_encoding = ");
 7041 tgl@sss.pgh.pa.us        3775                 :            185 :     appendStringLiteralAH(qry, encname, AH);
 4310 heikki.linnakangas@i     3776                 :            185 :     appendPQExpBufferStr(qry, ";\n");
                               3777                 :                : 
 7865 tgl@sss.pgh.pa.us        3778                 :            185 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3779                 :            185 :                  ARCHIVE_OPTS(.tag = "ENCODING",
                               3780                 :                :                               .description = "ENCODING",
                               3781                 :                :                               .section = SECTION_PRE_DATA,
                               3782                 :                :                               .createStmt = qry->data));
                               3783                 :                : 
 7865 tgl@sss.pgh.pa.us        3784                 :            185 :     destroyPQExpBuffer(qry);
                               3785                 :            185 : }
                               3786                 :                : 
                               3787                 :                : 
                               3788                 :                : /*
                               3789                 :                :  * dumpStdStrings: put the correct escape string behavior into the archive
                               3790                 :                :  */
                               3791                 :                : static void
 7043 bruce@momjian.us         3792                 :            185 : dumpStdStrings(Archive *AH)
                               3793                 :                : {
 7041 tgl@sss.pgh.pa.us        3794         [ +  - ]:            185 :     const char *stdstrings = AH->std_strings ? "on" : "off";
                               3795                 :            185 :     PQExpBuffer qry = createPQExpBuffer();
                               3796                 :                : 
  477 peter@eisentraut.org     3797                 :            185 :     pg_log_info("saving \"standard_conforming_strings = %s\"",
                               3798                 :                :                 stdstrings);
                               3799                 :                : 
 7041 tgl@sss.pgh.pa.us        3800                 :            185 :     appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
                               3801                 :                :                       stdstrings);
                               3802                 :                : 
 7043 bruce@momjian.us         3803                 :            185 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3804                 :            185 :                  ARCHIVE_OPTS(.tag = "STDSTRINGS",
                               3805                 :                :                               .description = "STDSTRINGS",
                               3806                 :                :                               .section = SECTION_PRE_DATA,
                               3807                 :                :                               .createStmt = qry->data));
                               3808                 :                : 
 7043 bruce@momjian.us         3809                 :            185 :     destroyPQExpBuffer(qry);
                               3810                 :            185 : }
                               3811                 :                : 
                               3812                 :                : /*
                               3813                 :                :  * dumpSearchPath: record the active search_path in the archive
                               3814                 :                :  */
                               3815                 :                : static void
 2749 tgl@sss.pgh.pa.us        3816                 :            185 : dumpSearchPath(Archive *AH)
                               3817                 :                : {
                               3818                 :            185 :     PQExpBuffer qry = createPQExpBuffer();
                               3819                 :            185 :     PQExpBuffer path = createPQExpBuffer();
                               3820                 :                :     PGresult   *res;
                               3821                 :            185 :     char      **schemanames = NULL;
                               3822                 :            185 :     int         nschemanames = 0;
                               3823                 :                :     int         i;
                               3824                 :                : 
                               3825                 :                :     /*
                               3826                 :                :      * We use the result of current_schemas(), not the search_path GUC,
                               3827                 :                :      * because that might contain wildcards such as "$user", which won't
                               3828                 :                :      * necessarily have the same value during restore.  Also, this way avoids
                               3829                 :                :      * listing schemas that may appear in search_path but not actually exist,
                               3830                 :                :      * which seems like a prudent exclusion.
                               3831                 :                :      */
                               3832                 :            185 :     res = ExecuteSqlQueryForSingleRow(AH,
                               3833                 :                :                                       "SELECT pg_catalog.current_schemas(false)");
                               3834                 :                : 
                               3835         [ -  + ]:            185 :     if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
 1247 tgl@sss.pgh.pa.us        3836                 :UBC           0 :         pg_fatal("could not parse result of current_schemas()");
                               3837                 :                : 
                               3838                 :                :     /*
                               3839                 :                :      * We use set_config(), not a simple "SET search_path" command, because
                               3840                 :                :      * the latter has less-clean behavior if the search path is empty.  While
                               3841                 :                :      * that's likely to get fixed at some point, it seems like a good idea to
                               3842                 :                :      * be as backwards-compatible as possible in what we put into archives.
                               3843                 :                :      */
 2749 tgl@sss.pgh.pa.us        3844         [ -  + ]:CBC         185 :     for (i = 0; i < nschemanames; i++)
                               3845                 :                :     {
 2749 tgl@sss.pgh.pa.us        3846         [ #  # ]:UBC           0 :         if (i > 0)
                               3847                 :              0 :             appendPQExpBufferStr(path, ", ");
                               3848                 :              0 :         appendPQExpBufferStr(path, fmtId(schemanames[i]));
                               3849                 :                :     }
                               3850                 :                : 
 2749 tgl@sss.pgh.pa.us        3851                 :CBC         185 :     appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
                               3852                 :            185 :     appendStringLiteralAH(qry, path->data, AH);
                               3853                 :            185 :     appendPQExpBufferStr(qry, ", false);\n");
                               3854                 :                : 
  477 peter@eisentraut.org     3855                 :            185 :     pg_log_info("saving \"search_path = %s\"", path->data);
                               3856                 :                : 
 2749 tgl@sss.pgh.pa.us        3857                 :            185 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.     3858                 :            185 :                  ARCHIVE_OPTS(.tag = "SEARCHPATH",
                               3859                 :                :                               .description = "SEARCHPATH",
                               3860                 :                :                               .section = SECTION_PRE_DATA,
                               3861                 :                :                               .createStmt = qry->data));
                               3862                 :                : 
                               3863                 :                :     /* Also save it in AH->searchpath, in case we're doing plain text dump */
 2749 tgl@sss.pgh.pa.us        3864                 :            185 :     AH->searchpath = pg_strdup(qry->data);
                               3865                 :                : 
 1178 peter@eisentraut.org     3866                 :            185 :     free(schemanames);
 2749 tgl@sss.pgh.pa.us        3867                 :            185 :     PQclear(res);
                               3868                 :            185 :     destroyPQExpBuffer(qry);
                               3869                 :            185 :     destroyPQExpBuffer(path);
                               3870                 :            185 : }
                               3871                 :                : 
                               3872                 :                : 
                               3873                 :                : /*
                               3874                 :                :  * getLOs:
                               3875                 :                :  *  Collect schema-level data about large objects
                               3876                 :                :  */
                               3877                 :                : static void
 1006 peter@eisentraut.org     3878                 :            157 : getLOs(Archive *fout)
                               3879                 :                : {
 3440 sfrost@snowman.net       3880                 :            157 :     DumpOptions *dopt = fout->dopt;
 1006 peter@eisentraut.org     3881                 :            157 :     PQExpBuffer loQry = createPQExpBuffer();
                               3882                 :                :     PGresult   *res;
                               3883                 :                :     int         ntups;
                               3884                 :                :     int         i;
                               3885                 :                :     int         n;
                               3886                 :                :     int         i_oid;
                               3887                 :                :     int         i_lomowner;
                               3888                 :                :     int         i_lomacl;
                               3889                 :                :     int         i_acldefault;
                               3890                 :                : 
 2350                          3891                 :            157 :     pg_log_info("reading large objects");
                               3892                 :                : 
                               3893                 :                :     /*
                               3894                 :                :      * Fetch LO OIDs and owner/ACL data.  Order the data so that all the blobs
                               3895                 :                :      * with the same owner/ACL appear together.
                               3896                 :                :      */
 1006                          3897                 :            157 :     appendPQExpBufferStr(loQry,
                               3898                 :                :                          "SELECT oid, lomowner, lomacl, "
                               3899                 :                :                          "acldefault('L', lomowner) AS acldefault "
                               3900                 :                :                          "FROM pg_largeobject_metadata "
                               3901                 :                :                          "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
                               3902                 :                : 
                               3903                 :            157 :     res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
                               3904                 :                : 
 3440 sfrost@snowman.net       3905                 :            157 :     i_oid = PQfnumber(res, "oid");
 1345 tgl@sss.pgh.pa.us        3906                 :            157 :     i_lomowner = PQfnumber(res, "lomowner");
 3440 sfrost@snowman.net       3907                 :            157 :     i_lomacl = PQfnumber(res, "lomacl");
 1370 tgl@sss.pgh.pa.us        3908                 :            157 :     i_acldefault = PQfnumber(res, "acldefault");
                               3909                 :                : 
 5679                          3910                 :            157 :     ntups = PQntuples(res);
                               3911                 :                : 
                               3912                 :                :     /*
                               3913                 :                :      * Group the blobs into suitably-sized groups that have the same owner and
                               3914                 :                :      * ACL setting, and build a metadata and a data DumpableObject for each
                               3915                 :                :      * group.  (If we supported initprivs for blobs, we'd have to insist that
                               3916                 :                :      * groups also share initprivs settings, since the DumpableObject only has
                               3917                 :                :      * room for one.)  i is the index of the first tuple in the current group,
                               3918                 :                :      * and n is the number of tuples we include in the group.
                               3919                 :                :      */
  523                          3920         [ +  + ]:            242 :     for (i = 0; i < ntups; i += n)
                               3921                 :                :     {
                               3922                 :             85 :         Oid         thisoid = atooid(PQgetvalue(res, i, i_oid));
                               3923                 :             85 :         char       *thisowner = PQgetvalue(res, i, i_lomowner);
                               3924                 :             85 :         char       *thisacl = PQgetvalue(res, i, i_lomacl);
                               3925                 :                :         LoInfo     *loinfo;
                               3926                 :                :         DumpableObject *lodata;
                               3927                 :                :         char        namebuf[64];
                               3928                 :                : 
                               3929                 :                :         /* Scan to find first tuple not to be included in group */
                               3930                 :             85 :         n = 1;
                               3931   [ +  -  +  + ]:             95 :         while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
                               3932                 :                :         {
                               3933         [ +  - ]:             50 :             if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
                               3934         [ +  + ]:             50 :                 strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
                               3935                 :                :                 break;
                               3936                 :             10 :             n++;
                               3937                 :                :         }
                               3938                 :                : 
                               3939                 :                :         /* Build the metadata DumpableObject */
                               3940                 :             85 :         loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
                               3941                 :                : 
                               3942                 :             85 :         loinfo->dobj.objType = DO_LARGE_OBJECT;
                               3943                 :             85 :         loinfo->dobj.catId.tableoid = LargeObjectRelationId;
                               3944                 :             85 :         loinfo->dobj.catId.oid = thisoid;
                               3945                 :             85 :         AssignDumpId(&loinfo->dobj);
                               3946                 :                : 
                               3947         [ +  + ]:             85 :         if (n > 1)
                               3948                 :              5 :             snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
                               3949                 :              5 :                      atooid(PQgetvalue(res, i + n - 1, i_oid)));
                               3950                 :                :         else
                               3951                 :             80 :             snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
                               3952                 :             85 :         loinfo->dobj.name = pg_strdup(namebuf);
                               3953                 :             85 :         loinfo->dacl.acl = pg_strdup(thisacl);
                               3954                 :             85 :         loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               3955                 :             85 :         loinfo->dacl.privtype = 0;
                               3956                 :             85 :         loinfo->dacl.initprivs = NULL;
                               3957                 :             85 :         loinfo->rolname = getRoleName(thisowner);
                               3958                 :             85 :         loinfo->numlos = n;
                               3959                 :             85 :         loinfo->looids[0] = thisoid;
                               3960                 :                :         /* Collect OIDs of the remaining blobs in this group */
                               3961         [ +  + ]:             95 :         for (int k = 1; k < n; k++)
                               3962                 :                :         {
                               3963                 :                :             CatalogId   extraID;
                               3964                 :                : 
                               3965                 :             10 :             loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
                               3966                 :                : 
                               3967                 :                :             /* Make sure we can look up loinfo by any of the blobs' OIDs */
                               3968                 :             10 :             extraID.tableoid = LargeObjectRelationId;
                               3969                 :             10 :             extraID.oid = loinfo->looids[k];
                               3970                 :             10 :             recordAdditionalCatalogID(extraID, &loinfo->dobj);
                               3971                 :                :         }
                               3972                 :                : 
                               3973                 :                :         /* LOs have data */
                               3974                 :             85 :         loinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               3975                 :                : 
                               3976                 :                :         /* Mark whether LO group has a non-empty ACL */
 1370                          3977         [ +  + ]:             85 :         if (!PQgetisnull(res, i, i_lomacl))
  523                          3978                 :             40 :             loinfo->dobj.components |= DUMP_COMPONENT_ACL;
                               3979                 :                : 
                               3980                 :                :         /*
                               3981                 :                :          * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
                               3982                 :                :          * as it will be copied by pg_upgrade, which simply copies the
                               3983                 :                :          * pg_largeobject table. We *do* however dump out anything but the
                               3984                 :                :          * data, as pg_upgrade copies just pg_largeobject, but not
                               3985                 :                :          * pg_largeobject_metadata, after the dump is restored.  In versions
                               3986                 :                :          * before v12, this is done via proper large object commands.  In
                               3987                 :                :          * newer versions, we dump the content of pg_largeobject_metadata and
                               3988                 :                :          * any associated pg_shdepend rows, which is faster to restore.  (On
                               3989                 :                :          * <v12, pg_largeobject_metadata was created WITH OIDS, so the OID
                               3990                 :                :          * column is hidden and won't be dumped.)
                               3991                 :                :          */
 3106 sfrost@snowman.net       3992         [ +  + ]:             85 :         if (dopt->binary_upgrade)
                               3993                 :                :         {
   50 nathan@postgresql.or     3994         [ +  - ]:GNC           3 :             if (fout->remoteVersion >= 120000)
                               3995                 :                :             {
                               3996                 :                :                 /*
                               3997                 :                :                  * We should've saved pg_largeobject_metadata's dump ID before
                               3998                 :                :                  * this point.
                               3999                 :                :                  */
                               4000         [ -  + ]:              3 :                 Assert(lo_metadata_dumpId);
                               4001                 :                : 
                               4002                 :              3 :                 loinfo->dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL | DUMP_COMPONENT_DEFINITION);
                               4003                 :                : 
                               4004                 :                :                 /*
                               4005                 :                :                  * Mark the large object as dependent on
                               4006                 :                :                  * pg_largeobject_metadata so that any large object
                               4007                 :                :                  * comments/seclables are dumped after it.
                               4008                 :                :                  */
                               4009                 :              3 :                 loinfo->dobj.dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               4010                 :              3 :                 loinfo->dobj.dependencies[0] = lo_metadata_dumpId;
                               4011                 :              3 :                 loinfo->dobj.nDeps = loinfo->dobj.allocDeps = 1;
                               4012                 :                :             }
                               4013                 :                :             else
   50 nathan@postgresql.or     4014                 :UNC           0 :                 loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
                               4015                 :                :         }
                               4016                 :                : 
                               4017                 :                :         /*
                               4018                 :                :          * Create a "BLOBS" data item for the group, too. This is just a
                               4019                 :                :          * placeholder for sorting; it carries no data now.
                               4020                 :                :          */
 1006 peter@eisentraut.org     4021                 :CBC          85 :         lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
                               4022                 :             85 :         lodata->objType = DO_LARGE_OBJECT_DATA;
                               4023                 :             85 :         lodata->catId = nilCatalogId;
                               4024                 :             85 :         AssignDumpId(lodata);
  523 tgl@sss.pgh.pa.us        4025                 :             85 :         lodata->name = pg_strdup(namebuf);
 1006 peter@eisentraut.org     4026                 :             85 :         lodata->components |= DUMP_COMPONENT_DATA;
                               4027                 :                :         /* Set up explicit dependency from data to metadata */
  523 tgl@sss.pgh.pa.us        4028                 :             85 :         lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               4029                 :             85 :         lodata->dependencies[0] = loinfo->dobj.dumpId;
                               4030                 :             85 :         lodata->nDeps = lodata->allocDeps = 1;
                               4031                 :                :     }
                               4032                 :                : 
 7373                          4033                 :            157 :     PQclear(res);
 1006 peter@eisentraut.org     4034                 :            157 :     destroyPQExpBuffer(loQry);
 5679 tgl@sss.pgh.pa.us        4035                 :            157 : }
                               4036                 :                : 
                               4037                 :                : /*
                               4038                 :                :  * dumpLO
                               4039                 :                :  *
                               4040                 :                :  * dump the definition (metadata) of the given large object group
                               4041                 :                :  */
                               4042                 :                : static void
 1006 peter@eisentraut.org     4043                 :             84 : dumpLO(Archive *fout, const LoInfo *loinfo)
                               4044                 :                : {
 5671 bruce@momjian.us         4045                 :             84 :     PQExpBuffer cquery = createPQExpBuffer();
                               4046                 :                : 
                               4047                 :                :     /*
                               4048                 :                :      * The "definition" is just a newline-separated list of OIDs.  We need to
                               4049                 :                :      * put something into the dropStmt too, but it can just be a comment.
                               4050                 :                :      */
  523 tgl@sss.pgh.pa.us        4051         [ +  + ]:            178 :     for (int i = 0; i < loinfo->numlos; i++)
                               4052                 :             94 :         appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
                               4053                 :                : 
 1006 peter@eisentraut.org     4054         [ +  + ]:             84 :     if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4055                 :             82 :         ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
                               4056                 :             82 :                      ARCHIVE_OPTS(.tag = loinfo->dobj.name,
                               4057                 :                :                                   .owner = loinfo->rolname,
                               4058                 :                :                                   .description = "BLOB METADATA",
                               4059                 :                :                                   .section = SECTION_DATA,
                               4060                 :                :                                   .createStmt = cquery->data,
                               4061                 :                :                                   .dropStmt = "-- dummy"));
                               4062                 :                : 
                               4063                 :                :     /*
                               4064                 :                :      * Dump per-blob comments and seclabels if any.  We assume these are rare
                               4065                 :                :      * enough that it's okay to generate retail TOC entries for them.
                               4066                 :                :      */
  523 tgl@sss.pgh.pa.us        4067         [ +  + ]:             84 :     if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
                               4068                 :                :                              DUMP_COMPONENT_SECLABEL))
                               4069                 :                :     {
                               4070         [ +  + ]:            100 :         for (int i = 0; i < loinfo->numlos; i++)
                               4071                 :                :         {
                               4072                 :                :             CatalogId   catId;
                               4073                 :                :             char        namebuf[32];
                               4074                 :                : 
                               4075                 :                :             /* Build identifying info for this blob */
                               4076                 :             55 :             catId.tableoid = loinfo->dobj.catId.tableoid;
                               4077                 :             55 :             catId.oid = loinfo->looids[i];
                               4078                 :             55 :             snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
                               4079                 :                : 
                               4080         [ +  - ]:             55 :             if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                               4081                 :             55 :                 dumpComment(fout, "LARGE OBJECT", namebuf,
                               4082                 :             55 :                             NULL, loinfo->rolname,
                               4083                 :             55 :                             catId, 0, loinfo->dobj.dumpId);
                               4084                 :                : 
                               4085         [ -  + ]:             55 :             if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
  523 tgl@sss.pgh.pa.us        4086                 :UBC           0 :                 dumpSecLabel(fout, "LARGE OBJECT", namebuf,
                               4087                 :              0 :                              NULL, loinfo->rolname,
                               4088                 :              0 :                              catId, 0, loinfo->dobj.dumpId);
                               4089                 :                :         }
                               4090                 :                :     }
                               4091                 :                : 
                               4092                 :                :     /*
                               4093                 :                :      * Dump the ACLs if any (remember that all blobs in the group will have
                               4094                 :                :      * the same ACL).  If there's just one blob, dump a simple ACL entry; if
                               4095                 :                :      * there's more, make a "LARGE OBJECTS" entry that really contains only
                               4096                 :                :      * the ACL for the first blob.  _printTocEntry() will be cued by the tag
                               4097                 :                :      * string to emit a mutated version for each blob.
                               4098                 :                :      */
 1006 peter@eisentraut.org     4099         [ +  + ]:CBC          84 :     if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
                               4100                 :                :     {
                               4101                 :                :         char        namebuf[32];
                               4102                 :                : 
                               4103                 :                :         /* Build identifying info for the first blob */
  523 tgl@sss.pgh.pa.us        4104                 :             39 :         snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
                               4105                 :                : 
                               4106         [ -  + ]:             39 :         if (loinfo->numlos > 1)
                               4107                 :                :         {
                               4108                 :                :             char        tagbuf[64];
                               4109                 :                : 
  523 tgl@sss.pgh.pa.us        4110                 :UBC           0 :             snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
                               4111                 :              0 :                      loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
                               4112                 :                : 
                               4113                 :              0 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               4114                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               4115                 :              0 :                     tagbuf, loinfo->rolname, &loinfo->dacl);
                               4116                 :                :         }
                               4117                 :                :         else
                               4118                 :                :         {
  523 tgl@sss.pgh.pa.us        4119                 :CBC          39 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               4120                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               4121                 :             39 :                     NULL, loinfo->rolname, &loinfo->dacl);
                               4122                 :                :         }
                               4123                 :                :     }
                               4124                 :                : 
 5679                          4125                 :             84 :     destroyPQExpBuffer(cquery);
 7373                          4126                 :             84 : }
                               4127                 :                : 
                               4128                 :                : /*
                               4129                 :                :  * dumpLOs:
                               4130                 :                :  *  dump the data contents of the large objects in the given group
                               4131                 :                :  */
                               4132                 :                : static int
 1006 peter@eisentraut.org     4133                 :             78 : dumpLOs(Archive *fout, const void *arg)
                               4134                 :                : {
  523 tgl@sss.pgh.pa.us        4135                 :             78 :     const LoInfo *loinfo = (const LoInfo *) arg;
 4951 rhaas@postgresql.org     4136                 :             78 :     PGconn     *conn = GetConnection(fout);
                               4137                 :                :     char        buf[LOBBUFSIZE];
                               4138                 :                : 
  523 tgl@sss.pgh.pa.us        4139                 :             78 :     pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
                               4140                 :                : 
                               4141         [ +  + ]:            164 :     for (int i = 0; i < loinfo->numlos; i++)
                               4142                 :                :     {
                               4143                 :             86 :         Oid         loOid = loinfo->looids[i];
                               4144                 :                :         int         loFd;
                               4145                 :                :         int         cnt;
                               4146                 :                : 
                               4147                 :                :         /* Open the LO */
                               4148                 :             86 :         loFd = lo_open(conn, loOid, INV_READ);
                               4149         [ -  + ]:             86 :         if (loFd == -1)
  523 tgl@sss.pgh.pa.us        4150                 :UBC           0 :             pg_fatal("could not open large object %u: %s",
                               4151                 :                :                      loOid, PQerrorMessage(conn));
                               4152                 :                : 
  523 tgl@sss.pgh.pa.us        4153                 :CBC          86 :         StartLO(fout, loOid);
                               4154                 :                : 
                               4155                 :                :         /* Now read it in chunks, sending data to archive */
                               4156                 :                :         do
                               4157                 :                :         {
                               4158                 :            131 :             cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                               4159         [ -  + ]:            131 :             if (cnt < 0)
  523 tgl@sss.pgh.pa.us        4160                 :UBC           0 :                 pg_fatal("error reading large object %u: %s",
                               4161                 :                :                          loOid, PQerrorMessage(conn));
                               4162                 :                : 
  523 tgl@sss.pgh.pa.us        4163                 :CBC         131 :             WriteData(fout, buf, cnt);
                               4164         [ +  + ]:            131 :         } while (cnt > 0);
                               4165                 :                : 
                               4166                 :             86 :         lo_close(conn, loFd);
                               4167                 :                : 
                               4168                 :             86 :         EndLO(fout, loOid);
                               4169                 :                :     }
                               4170                 :                : 
 7373                          4171                 :             78 :     return 1;
                               4172                 :                : }
                               4173                 :                : 
                               4174                 :                : /*
                               4175                 :                :  * getPolicies
                               4176                 :                :  *    get information about all RLS policies on dumpable tables.
                               4177                 :                :  */
                               4178                 :                : void
 3936 sfrost@snowman.net       4179                 :            185 : getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                               4180                 :                : {
  174 tgl@sss.pgh.pa.us        4181                 :            185 :     DumpOptions *dopt = fout->dopt;
                               4182                 :                :     PQExpBuffer query;
                               4183                 :                :     PQExpBuffer tbloids;
                               4184                 :                :     PGresult   *res;
                               4185                 :                :     PolicyInfo *polinfo;
                               4186                 :                :     int         i_oid;
                               4187                 :                :     int         i_tableoid;
                               4188                 :                :     int         i_polrelid;
                               4189                 :                :     int         i_polname;
                               4190                 :                :     int         i_polcmd;
                               4191                 :                :     int         i_polpermissive;
                               4192                 :                :     int         i_polroles;
                               4193                 :                :     int         i_polqual;
                               4194                 :                :     int         i_polwithcheck;
                               4195                 :                :     int         i,
                               4196                 :                :                 j,
                               4197                 :                :                 ntups;
                               4198                 :                : 
                               4199                 :                :     /* No policies before 9.5 */
 4005 sfrost@snowman.net       4200         [ -  + ]:            185 :     if (fout->remoteVersion < 90500)
 4005 sfrost@snowman.net       4201                 :UBC           0 :         return;
                               4202                 :                : 
                               4203                 :                :     /* Skip if --no-policies was specified */
  174 tgl@sss.pgh.pa.us        4204         [ +  + ]:CBC         185 :     if (dopt->no_policies)
                               4205                 :              1 :         return;
                               4206                 :                : 
 4000 sfrost@snowman.net       4207                 :            184 :     query = createPQExpBuffer();
 1345 tgl@sss.pgh.pa.us        4208                 :            184 :     tbloids = createPQExpBuffer();
                               4209                 :                : 
                               4210                 :                :     /*
                               4211                 :                :      * Identify tables of interest, and check which ones have RLS enabled.
                               4212                 :                :      */
                               4213                 :            184 :     appendPQExpBufferChar(tbloids, '{');
 4005 sfrost@snowman.net       4214         [ +  + ]:          48955 :     for (i = 0; i < numTables; i++)
                               4215                 :                :     {
 3977 tgl@sss.pgh.pa.us        4216                 :          48771 :         TableInfo  *tbinfo = &tblinfo[i];
                               4217                 :                : 
                               4218                 :                :         /* Ignore row security on tables not to be dumped */
 3440 sfrost@snowman.net       4219         [ +  + ]:          48771 :         if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
 4005                          4220                 :          41490 :             continue;
                               4221                 :                : 
                               4222                 :                :         /* It can't have RLS or policies if it's not a table */
 1345 tgl@sss.pgh.pa.us        4223         [ +  + ]:           7281 :         if (tbinfo->relkind != RELKIND_RELATION &&
                               4224         [ +  + ]:           2077 :             tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
                               4225                 :           1467 :             continue;
                               4226                 :                : 
                               4227                 :                :         /* Add it to the list of table OIDs to be probed below */
                               4228         [ +  + ]:           5814 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               4229                 :           5694 :             appendPQExpBufferChar(tbloids, ',');
                               4230                 :           5814 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               4231                 :                : 
                               4232                 :                :         /* Is RLS enabled?  (That's separate from whether it has policies) */
 4000 sfrost@snowman.net       4233         [ +  + ]:           5814 :         if (tbinfo->rowsec)
                               4234                 :                :         {
 1370 tgl@sss.pgh.pa.us        4235                 :             59 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               4236                 :                : 
                               4237                 :                :             /*
                               4238                 :                :              * We represent RLS being enabled on a table by creating a
                               4239                 :                :              * PolicyInfo object with null polname.
                               4240                 :                :              *
                               4241                 :                :              * Note: use tableoid 0 so that this object won't be mistaken for
                               4242                 :                :              * something that pg_depend entries apply to.
                               4243                 :                :              */
 3936 sfrost@snowman.net       4244                 :             59 :             polinfo = pg_malloc(sizeof(PolicyInfo));
                               4245                 :             59 :             polinfo->dobj.objType = DO_POLICY;
                               4246                 :             59 :             polinfo->dobj.catId.tableoid = 0;
                               4247                 :             59 :             polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               4248                 :             59 :             AssignDumpId(&polinfo->dobj);
                               4249                 :             59 :             polinfo->dobj.namespace = tbinfo->dobj.namespace;
                               4250                 :             59 :             polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
                               4251                 :             59 :             polinfo->poltable = tbinfo;
                               4252                 :             59 :             polinfo->polname = NULL;
 3197                          4253                 :             59 :             polinfo->polcmd = '\0';
                               4254                 :             59 :             polinfo->polpermissive = 0;
 3936                          4255                 :             59 :             polinfo->polroles = NULL;
                               4256                 :             59 :             polinfo->polqual = NULL;
                               4257                 :             59 :             polinfo->polwithcheck = NULL;
                               4258                 :                :         }
                               4259                 :                :     }
 1345 tgl@sss.pgh.pa.us        4260                 :            184 :     appendPQExpBufferChar(tbloids, '}');
                               4261                 :                : 
                               4262                 :                :     /*
                               4263                 :                :      * Now, read all RLS policies belonging to the tables of interest, and
                               4264                 :                :      * create PolicyInfo objects for them.  (Note that we must filter the
                               4265                 :                :      * results server-side not locally, because we dare not apply pg_get_expr
                               4266                 :                :      * to tables we don't have lock on.)
                               4267                 :                :      */
 1467                          4268                 :            184 :     pg_log_info("reading row-level security policies");
                               4269                 :                : 
                               4270                 :            184 :     printfPQExpBuffer(query,
                               4271                 :                :                       "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
                               4272         [ +  - ]:            184 :     if (fout->remoteVersion >= 100000)
 1096 drowley@postgresql.o     4273                 :            184 :         appendPQExpBufferStr(query, "pol.polpermissive, ");
                               4274                 :                :     else
 1096 drowley@postgresql.o     4275                 :UBC           0 :         appendPQExpBufferStr(query, "'t' as polpermissive, ");
 1467 tgl@sss.pgh.pa.us        4276                 :CBC         184 :     appendPQExpBuffer(query,
                               4277                 :                :                       "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
                               4278                 :                :                       "   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, "
                               4279                 :                :                       "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
                               4280                 :                :                       "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
                               4281                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               4282                 :                :                       "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
                               4283                 :                :                       tbloids->data);
                               4284                 :                : 
                               4285                 :            184 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4286                 :                : 
                               4287                 :            184 :     ntups = PQntuples(res);
                               4288         [ +  + ]:            184 :     if (ntups > 0)
                               4289                 :                :     {
 4005 sfrost@snowman.net       4290                 :             49 :         i_oid = PQfnumber(res, "oid");
                               4291                 :             49 :         i_tableoid = PQfnumber(res, "tableoid");
 1467 tgl@sss.pgh.pa.us        4292                 :             49 :         i_polrelid = PQfnumber(res, "polrelid");
 3936 sfrost@snowman.net       4293                 :             49 :         i_polname = PQfnumber(res, "polname");
                               4294                 :             49 :         i_polcmd = PQfnumber(res, "polcmd");
 3197                          4295                 :             49 :         i_polpermissive = PQfnumber(res, "polpermissive");
 3936                          4296                 :             49 :         i_polroles = PQfnumber(res, "polroles");
                               4297                 :             49 :         i_polqual = PQfnumber(res, "polqual");
                               4298                 :             49 :         i_polwithcheck = PQfnumber(res, "polwithcheck");
                               4299                 :                : 
                               4300                 :             49 :         polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
                               4301                 :                : 
 4005                          4302         [ +  + ]:            358 :         for (j = 0; j < ntups; j++)
                               4303                 :                :         {
 1467 tgl@sss.pgh.pa.us        4304                 :            309 :             Oid         polrelid = atooid(PQgetvalue(res, j, i_polrelid));
                               4305                 :            309 :             TableInfo  *tbinfo = findTableByOid(polrelid);
                               4306                 :                : 
 1370                          4307                 :            309 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               4308                 :                : 
 3936 sfrost@snowman.net       4309                 :            309 :             polinfo[j].dobj.objType = DO_POLICY;
                               4310                 :            309 :             polinfo[j].dobj.catId.tableoid =
 4005                          4311                 :            309 :                 atooid(PQgetvalue(res, j, i_tableoid));
 3936                          4312                 :            309 :             polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               4313                 :            309 :             AssignDumpId(&polinfo[j].dobj);
                               4314                 :            309 :             polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4315                 :            309 :             polinfo[j].poltable = tbinfo;
                               4316                 :            309 :             polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
                               4317                 :            309 :             polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
                               4318                 :                : 
 3197                          4319                 :            309 :             polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
                               4320                 :            309 :             polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
                               4321                 :                : 
                               4322         [ +  + ]:            309 :             if (PQgetisnull(res, j, i_polroles))
                               4323                 :            133 :                 polinfo[j].polroles = NULL;
                               4324                 :                :             else
                               4325                 :            176 :                 polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
                               4326                 :                : 
 3936                          4327         [ +  + ]:            309 :             if (PQgetisnull(res, j, i_polqual))
                               4328                 :             44 :                 polinfo[j].polqual = NULL;
                               4329                 :                :             else
                               4330                 :            265 :                 polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
                               4331                 :                : 
                               4332         [ +  + ]:            309 :             if (PQgetisnull(res, j, i_polwithcheck))
                               4333                 :            162 :                 polinfo[j].polwithcheck = NULL;
                               4334                 :                :             else
                               4335                 :            147 :                 polinfo[j].polwithcheck
                               4336                 :            147 :                     = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
                               4337                 :                :         }
                               4338                 :                :     }
                               4339                 :                : 
 1467 tgl@sss.pgh.pa.us        4340                 :            184 :     PQclear(res);
                               4341                 :                : 
 4005 sfrost@snowman.net       4342                 :            184 :     destroyPQExpBuffer(query);
 1345 tgl@sss.pgh.pa.us        4343                 :            184 :     destroyPQExpBuffer(tbloids);
                               4344                 :                : }
                               4345                 :                : 
                               4346                 :                : /*
                               4347                 :                :  * dumpPolicy
                               4348                 :                :  *    dump the definition of the given policy
                               4349                 :                :  */
                               4350                 :                : static void
 1669 peter@eisentraut.org     4351                 :            368 : dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
                               4352                 :                : {
 3524 tgl@sss.pgh.pa.us        4353                 :            368 :     DumpOptions *dopt = fout->dopt;
 3936 sfrost@snowman.net       4354                 :            368 :     TableInfo  *tbinfo = polinfo->poltable;
                               4355                 :                :     PQExpBuffer query;
                               4356                 :                :     PQExpBuffer delqry;
                               4357                 :                :     PQExpBuffer polprefix;
                               4358                 :                :     char       *qtabname;
                               4359                 :                :     const char *cmd;
                               4360                 :                :     char       *tag;
                               4361                 :                : 
                               4362                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     4363         [ +  + ]:            368 :     if (!dopt->dumpSchema)
 4005 sfrost@snowman.net       4364                 :             49 :         return;
                               4365                 :                : 
                               4366                 :                :     /*
                               4367                 :                :      * If polname is NULL, then this record is just indicating that ROW LEVEL
                               4368                 :                :      * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
                               4369                 :                :      * ROW LEVEL SECURITY.
                               4370                 :                :      */
 3936                          4371         [ +  + ]:            319 :     if (polinfo->polname == NULL)
                               4372                 :                :     {
 4005                          4373                 :             52 :         query = createPQExpBuffer();
                               4374                 :                : 
                               4375                 :             52 :         appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
 2567 tgl@sss.pgh.pa.us        4376                 :             52 :                           fmtQualifiedDumpable(tbinfo));
                               4377                 :                : 
                               4378                 :                :         /*
                               4379                 :                :          * We must emit the ROW SECURITY object's dependency on its table
                               4380                 :                :          * explicitly, because it will not match anything in pg_depend (unlike
                               4381                 :                :          * the case for other PolicyInfo objects).
                               4382                 :                :          */
 1370                          4383         [ +  - ]:             52 :         if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3440 sfrost@snowman.net       4384                 :             52 :             ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.     4385                 :             52 :                          ARCHIVE_OPTS(.tag = polinfo->dobj.name,
                               4386                 :                :                                       .namespace = polinfo->dobj.namespace->dobj.name,
                               4387                 :                :                                       .owner = tbinfo->rolname,
                               4388                 :                :                                       .description = "ROW SECURITY",
                               4389                 :                :                                       .section = SECTION_POST_DATA,
                               4390                 :                :                                       .createStmt = query->data,
                               4391                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                               4392                 :                :                                       .nDeps = 1));
                               4393                 :                : 
 4005 sfrost@snowman.net       4394                 :             52 :         destroyPQExpBuffer(query);
                               4395                 :             52 :         return;
                               4396                 :                :     }
                               4397                 :                : 
 3197                          4398         [ +  + ]:            267 :     if (polinfo->polcmd == '*')
                               4399                 :             89 :         cmd = "";
                               4400         [ +  + ]:            178 :     else if (polinfo->polcmd == 'r')
                               4401                 :             47 :         cmd = " FOR SELECT";
                               4402         [ +  + ]:            131 :     else if (polinfo->polcmd == 'a')
                               4403                 :             37 :         cmd = " FOR INSERT";
                               4404         [ +  + ]:             94 :     else if (polinfo->polcmd == 'w')
                               4405                 :             47 :         cmd = " FOR UPDATE";
                               4406         [ +  - ]:             47 :     else if (polinfo->polcmd == 'd')
                               4407                 :             47 :         cmd = " FOR DELETE";
                               4408                 :                :     else
 1247 tgl@sss.pgh.pa.us        4409                 :UBC           0 :         pg_fatal("unexpected policy command type: %c",
                               4410                 :                :                  polinfo->polcmd);
                               4411                 :                : 
 4005 sfrost@snowman.net       4412                 :CBC         267 :     query = createPQExpBuffer();
                               4413                 :            267 :     delqry = createPQExpBuffer();
 2028 tgl@sss.pgh.pa.us        4414                 :            267 :     polprefix = createPQExpBuffer();
                               4415                 :                : 
                               4416                 :            267 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                               4417                 :                : 
 3878                          4418                 :            267 :     appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
                               4419                 :                : 
 2749                          4420                 :            267 :     appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
 3197 sfrost@snowman.net       4421         [ +  + ]:            267 :                       !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
                               4422                 :                : 
 3936                          4423         [ +  + ]:            267 :     if (polinfo->polroles != NULL)
                               4424                 :            148 :         appendPQExpBuffer(query, " TO %s", polinfo->polroles);
                               4425                 :                : 
                               4426         [ +  + ]:            267 :     if (polinfo->polqual != NULL)
 3694 mail@joeconway.com       4427                 :            230 :         appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
                               4428                 :                : 
 3936 sfrost@snowman.net       4429         [ +  + ]:            267 :     if (polinfo->polwithcheck != NULL)
 3694 mail@joeconway.com       4430                 :            126 :         appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
                               4431                 :                : 
 2256 drowley@postgresql.o     4432                 :            267 :     appendPQExpBufferStr(query, ";\n");
                               4433                 :                : 
 3878 tgl@sss.pgh.pa.us        4434                 :            267 :     appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
 2749                          4435                 :            267 :     appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
                               4436                 :                : 
 2028                          4437                 :            267 :     appendPQExpBuffer(polprefix, "POLICY %s ON",
                               4438                 :            267 :                       fmtId(polinfo->polname));
                               4439                 :                : 
 3481 peter_e@gmx.net          4440                 :            267 :     tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
                               4441                 :                : 
 1370 tgl@sss.pgh.pa.us        4442         [ +  - ]:            267 :     if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3440 sfrost@snowman.net       4443                 :            267 :         ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.     4444                 :            267 :                      ARCHIVE_OPTS(.tag = tag,
                               4445                 :                :                                   .namespace = polinfo->dobj.namespace->dobj.name,
                               4446                 :                :                                   .owner = tbinfo->rolname,
                               4447                 :                :                                   .description = "POLICY",
                               4448                 :                :                                   .section = SECTION_POST_DATA,
                               4449                 :                :                                   .createStmt = query->data,
                               4450                 :                :                                   .dropStmt = delqry->data));
                               4451                 :                : 
 2028 tgl@sss.pgh.pa.us        4452         [ -  + ]:            267 :     if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2028 tgl@sss.pgh.pa.us        4453                 :UBC           0 :         dumpComment(fout, polprefix->data, qtabname,
                               4454                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                               4455                 :              0 :                     polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
                               4456                 :                : 
 3481 peter_e@gmx.net          4457                 :CBC         267 :     free(tag);
 4005 sfrost@snowman.net       4458                 :            267 :     destroyPQExpBuffer(query);
                               4459                 :            267 :     destroyPQExpBuffer(delqry);
 2028 tgl@sss.pgh.pa.us        4460                 :            267 :     destroyPQExpBuffer(polprefix);
                               4461                 :            267 :     free(qtabname);
                               4462                 :                : }
                               4463                 :                : 
                               4464                 :                : /*
                               4465                 :                :  * getPublications
                               4466                 :                :  *    get information about publications
                               4467                 :                :  */
                               4468                 :                : void
  431 nathan@postgresql.or     4469                 :            185 : getPublications(Archive *fout)
                               4470                 :                : {
 3039 peter_e@gmx.net          4471                 :            185 :     DumpOptions *dopt = fout->dopt;
                               4472                 :                :     PQExpBuffer query;
                               4473                 :                :     PGresult   *res;
                               4474                 :                :     PublicationInfo *pubinfo;
                               4475                 :                :     int         i_tableoid;
                               4476                 :                :     int         i_oid;
                               4477                 :                :     int         i_pubname;
                               4478                 :                :     int         i_pubowner;
                               4479                 :                :     int         i_puballtables;
                               4480                 :                :     int         i_pubinsert;
                               4481                 :                :     int         i_pubupdate;
                               4482                 :                :     int         i_pubdelete;
                               4483                 :                :     int         i_pubtruncate;
                               4484                 :                :     int         i_pubviaroot;
                               4485                 :                :     int         i_pubgencols;
                               4486                 :                :     int         i,
                               4487                 :                :                 ntups;
                               4488                 :                : 
                               4489   [ +  -  -  + ]:            185 :     if (dopt->no_publications || fout->remoteVersion < 100000)
  431 nathan@postgresql.or     4490                 :UBC           0 :         return;
                               4491                 :                : 
 3152 peter_e@gmx.net          4492                 :CBC         185 :     query = createPQExpBuffer();
                               4493                 :                : 
                               4494                 :                :     /* Get the publications. */
  303 akapila@postgresql.o     4495                 :            185 :     appendPQExpBufferStr(query, "SELECT p.tableoid, p.oid, p.pubname, "
                               4496                 :                :                          "p.pubowner, p.puballtables, p.pubinsert, "
                               4497                 :                :                          "p.pubupdate, p.pubdelete, ");
                               4498                 :                : 
                               4499         [ +  - ]:            185 :     if (fout->remoteVersion >= 110000)
                               4500                 :            185 :         appendPQExpBufferStr(query, "p.pubtruncate, ");
                               4501                 :                :     else
  303 akapila@postgresql.o     4502                 :UBC           0 :         appendPQExpBufferStr(query, "false AS pubtruncate, ");
                               4503                 :                : 
 1248 tomas.vondra@postgre     4504         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 130000)
  303 akapila@postgresql.o     4505                 :            185 :         appendPQExpBufferStr(query, "p.pubviaroot, ");
                               4506                 :                :     else
  303 akapila@postgresql.o     4507                 :UBC           0 :         appendPQExpBufferStr(query, "false AS pubviaroot, ");
                               4508                 :                : 
  303 akapila@postgresql.o     4509         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 180000)
  221                          4510                 :            185 :         appendPQExpBufferStr(query, "p.pubgencols ");
                               4511                 :                :     else
  221 akapila@postgresql.o     4512                 :UBC           0 :         appendPQExpBuffer(query, "'%c' AS pubgencols ", PUBLISH_GENCOLS_NONE);
                               4513                 :                : 
  303 akapila@postgresql.o     4514                 :CBC         185 :     appendPQExpBufferStr(query, "FROM pg_publication p");
                               4515                 :                : 
 3152 peter_e@gmx.net          4516                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4517                 :                : 
                               4518                 :            185 :     ntups = PQntuples(res);
                               4519                 :                : 
  339 dgustafsson@postgres     4520         [ +  + ]:            185 :     if (ntups == 0)
                               4521                 :            126 :         goto cleanup;
                               4522                 :                : 
 3152 peter_e@gmx.net          4523                 :             59 :     i_tableoid = PQfnumber(res, "tableoid");
                               4524                 :             59 :     i_oid = PQfnumber(res, "oid");
                               4525                 :             59 :     i_pubname = PQfnumber(res, "pubname");
 1345 tgl@sss.pgh.pa.us        4526                 :             59 :     i_pubowner = PQfnumber(res, "pubowner");
 3152 peter_e@gmx.net          4527                 :             59 :     i_puballtables = PQfnumber(res, "puballtables");
                               4528                 :             59 :     i_pubinsert = PQfnumber(res, "pubinsert");
                               4529                 :             59 :     i_pubupdate = PQfnumber(res, "pubupdate");
                               4530                 :             59 :     i_pubdelete = PQfnumber(res, "pubdelete");
 2709                          4531                 :             59 :     i_pubtruncate = PQfnumber(res, "pubtruncate");
 1977 peter@eisentraut.org     4532                 :             59 :     i_pubviaroot = PQfnumber(res, "pubviaroot");
  221 akapila@postgresql.o     4533                 :             59 :     i_pubgencols = PQfnumber(res, "pubgencols");
                               4534                 :                : 
 3152 peter_e@gmx.net          4535                 :             59 :     pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
                               4536                 :                : 
                               4537         [ +  + ]:            350 :     for (i = 0; i < ntups; i++)
                               4538                 :                :     {
                               4539                 :            291 :         pubinfo[i].dobj.objType = DO_PUBLICATION;
                               4540                 :            291 :         pubinfo[i].dobj.catId.tableoid =
                               4541                 :            291 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4542                 :            291 :         pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4543                 :            291 :         AssignDumpId(&pubinfo[i].dobj);
                               4544                 :            291 :         pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
 1345 tgl@sss.pgh.pa.us        4545                 :            291 :         pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
 3152 peter_e@gmx.net          4546                 :            291 :         pubinfo[i].puballtables =
                               4547                 :            291 :             (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
                               4548                 :            291 :         pubinfo[i].pubinsert =
                               4549                 :            291 :             (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
                               4550                 :            291 :         pubinfo[i].pubupdate =
                               4551                 :            291 :             (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
                               4552                 :            291 :         pubinfo[i].pubdelete =
                               4553                 :            291 :             (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
 2709                          4554                 :            291 :         pubinfo[i].pubtruncate =
                               4555                 :            291 :             (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
 1977 peter@eisentraut.org     4556                 :            291 :         pubinfo[i].pubviaroot =
                               4557                 :            291 :             (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
  226 akapila@postgresql.o     4558                 :            291 :         pubinfo[i].pubgencols_type =
  221                          4559                 :            291 :             *(PQgetvalue(res, i, i_pubgencols));
                               4560                 :                : 
                               4561                 :                :         /* Decide whether we want to dump it */
 3091 peter_e@gmx.net          4562                 :            291 :         selectDumpableObject(&(pubinfo[i].dobj), fout);
                               4563                 :                :     }
                               4564                 :                : 
  339 dgustafsson@postgres     4565                 :             59 : cleanup:
 3152 peter_e@gmx.net          4566                 :            185 :     PQclear(res);
                               4567                 :                : 
                               4568                 :            185 :     destroyPQExpBuffer(query);
                               4569                 :                : }
                               4570                 :                : 
                               4571                 :                : /*
                               4572                 :                :  * dumpPublication
                               4573                 :                :  *    dump the definition of the given publication
                               4574                 :                :  */
                               4575                 :                : static void
 1669 peter@eisentraut.org     4576                 :            241 : dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
                               4577                 :                : {
 1346 tgl@sss.pgh.pa.us        4578                 :            241 :     DumpOptions *dopt = fout->dopt;
                               4579                 :                :     PQExpBuffer delq;
                               4580                 :                :     PQExpBuffer query;
                               4581                 :                :     char       *qpubname;
 3039 peter_e@gmx.net          4582                 :            241 :     bool        first = true;
                               4583                 :                : 
                               4584                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     4585         [ +  + ]:            241 :     if (!dopt->dumpSchema)
 1346 tgl@sss.pgh.pa.us        4586                 :             30 :         return;
                               4587                 :                : 
 3152 peter_e@gmx.net          4588                 :            211 :     delq = createPQExpBuffer();
                               4589                 :            211 :     query = createPQExpBuffer();
                               4590                 :                : 
 2749 tgl@sss.pgh.pa.us        4591                 :            211 :     qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
                               4592                 :                : 
 3152 peter_e@gmx.net          4593                 :            211 :     appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
                               4594                 :                :                       qpubname);
                               4595                 :                : 
                               4596                 :            211 :     appendPQExpBuffer(query, "CREATE PUBLICATION %s",
                               4597                 :                :                       qpubname);
                               4598                 :                : 
                               4599         [ +  + ]:            211 :     if (pubinfo->puballtables)
                               4600                 :             38 :         appendPQExpBufferStr(query, " FOR ALL TABLES");
                               4601                 :                : 
 3039                          4602                 :            211 :     appendPQExpBufferStr(query, " WITH (publish = '");
 3152                          4603         [ +  + ]:            211 :     if (pubinfo->pubinsert)
                               4604                 :                :     {
 3039                          4605                 :            174 :         appendPQExpBufferStr(query, "insert");
                               4606                 :            174 :         first = false;
                               4607                 :                :     }
                               4608                 :                : 
 3152                          4609         [ +  + ]:            211 :     if (pubinfo->pubupdate)
                               4610                 :                :     {
 3036 tgl@sss.pgh.pa.us        4611         [ +  - ]:            174 :         if (!first)
                               4612                 :            174 :             appendPQExpBufferStr(query, ", ");
                               4613                 :                : 
 3039 peter_e@gmx.net          4614                 :            174 :         appendPQExpBufferStr(query, "update");
                               4615                 :            174 :         first = false;
                               4616                 :                :     }
                               4617                 :                : 
 3152                          4618         [ +  + ]:            211 :     if (pubinfo->pubdelete)
                               4619                 :                :     {
 3036 tgl@sss.pgh.pa.us        4620         [ +  - ]:            174 :         if (!first)
                               4621                 :            174 :             appendPQExpBufferStr(query, ", ");
                               4622                 :                : 
 3039 peter_e@gmx.net          4623                 :            174 :         appendPQExpBufferStr(query, "delete");
                               4624                 :            174 :         first = false;
                               4625                 :                :     }
                               4626                 :                : 
 2709                          4627         [ +  + ]:            211 :     if (pubinfo->pubtruncate)
                               4628                 :                :     {
                               4629         [ +  - ]:            174 :         if (!first)
                               4630                 :            174 :             appendPQExpBufferStr(query, ", ");
                               4631                 :                : 
                               4632                 :            174 :         appendPQExpBufferStr(query, "truncate");
                               4633                 :            174 :         first = false;
                               4634                 :                :     }
                               4635                 :                : 
 1096 drowley@postgresql.o     4636                 :            211 :     appendPQExpBufferChar(query, '\'');
                               4637                 :                : 
 1977 peter@eisentraut.org     4638         [ +  + ]:            211 :     if (pubinfo->pubviaroot)
                               4639                 :              5 :         appendPQExpBufferStr(query, ", publish_via_partition_root = true");
                               4640                 :                : 
  226 akapila@postgresql.o     4641         [ +  + ]:            211 :     if (pubinfo->pubgencols_type == PUBLISH_GENCOLS_STORED)
                               4642                 :             37 :         appendPQExpBufferStr(query, ", publish_generated_columns = stored");
                               4643                 :                : 
 1977 peter@eisentraut.org     4644                 :            211 :     appendPQExpBufferStr(query, ");\n");
                               4645                 :                : 
 1370 tgl@sss.pgh.pa.us        4646         [ +  - ]:            211 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4647                 :            211 :         ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
                               4648                 :            211 :                      ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
                               4649                 :                :                                   .owner = pubinfo->rolname,
                               4650                 :                :                                   .description = "PUBLICATION",
                               4651                 :                :                                   .section = SECTION_POST_DATA,
                               4652                 :                :                                   .createStmt = query->data,
                               4653                 :                :                                   .dropStmt = delq->data));
                               4654                 :                : 
 3068 peter_e@gmx.net          4655         [ +  + ]:            211 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us        4656                 :             37 :         dumpComment(fout, "PUBLICATION", qpubname,
 3068 peter_e@gmx.net          4657                 :             37 :                     NULL, pubinfo->rolname,
                               4658                 :             37 :                     pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4659                 :                : 
                               4660         [ -  + ]:            211 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us        4661                 :UBC           0 :         dumpSecLabel(fout, "PUBLICATION", qpubname,
 3068 peter_e@gmx.net          4662                 :              0 :                      NULL, pubinfo->rolname,
                               4663                 :              0 :                      pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4664                 :                : 
 3152 peter_e@gmx.net          4665                 :CBC         211 :     destroyPQExpBuffer(delq);
                               4666                 :            211 :     destroyPQExpBuffer(query);
 2749 tgl@sss.pgh.pa.us        4667                 :            211 :     free(qpubname);
                               4668                 :                : }
                               4669                 :                : 
                               4670                 :                : /*
                               4671                 :                :  * getPublicationNamespaces
                               4672                 :                :  *    get information about publication membership for dumpable schemas.
                               4673                 :                :  */
                               4674                 :                : void
 1410 akapila@postgresql.o     4675                 :            185 : getPublicationNamespaces(Archive *fout)
                               4676                 :                : {
                               4677                 :                :     PQExpBuffer query;
                               4678                 :                :     PGresult   *res;
                               4679                 :                :     PublicationSchemaInfo *pubsinfo;
                               4680                 :            185 :     DumpOptions *dopt = fout->dopt;
                               4681                 :                :     int         i_tableoid;
                               4682                 :                :     int         i_oid;
                               4683                 :                :     int         i_pnpubid;
                               4684                 :                :     int         i_pnnspid;
                               4685                 :                :     int         i,
                               4686                 :                :                 j,
                               4687                 :                :                 ntups;
                               4688                 :                : 
                               4689   [ +  -  -  + ]:            185 :     if (dopt->no_publications || fout->remoteVersion < 150000)
 1410 akapila@postgresql.o     4690                 :UBC           0 :         return;
                               4691                 :                : 
 1410 akapila@postgresql.o     4692                 :CBC         185 :     query = createPQExpBuffer();
                               4693                 :                : 
                               4694                 :                :     /* Collect all publication membership info. */
                               4695                 :            185 :     appendPQExpBufferStr(query,
                               4696                 :                :                          "SELECT tableoid, oid, pnpubid, pnnspid "
                               4697                 :                :                          "FROM pg_catalog.pg_publication_namespace");
                               4698                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4699                 :                : 
                               4700                 :            185 :     ntups = PQntuples(res);
                               4701                 :                : 
                               4702                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               4703                 :            185 :     i_oid = PQfnumber(res, "oid");
                               4704                 :            185 :     i_pnpubid = PQfnumber(res, "pnpubid");
                               4705                 :            185 :     i_pnnspid = PQfnumber(res, "pnnspid");
                               4706                 :                : 
                               4707                 :                :     /* this allocation may be more than we need */
                               4708                 :            185 :     pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
                               4709                 :            185 :     j = 0;
                               4710                 :                : 
                               4711         [ +  + ]:            322 :     for (i = 0; i < ntups; i++)
                               4712                 :                :     {
                               4713                 :            137 :         Oid         pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
                               4714                 :            137 :         Oid         pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
                               4715                 :                :         PublicationInfo *pubinfo;
                               4716                 :                :         NamespaceInfo *nspinfo;
                               4717                 :                : 
                               4718                 :                :         /*
                               4719                 :                :          * Ignore any entries for which we aren't interested in either the
                               4720                 :                :          * publication or the rel.
                               4721                 :                :          */
                               4722                 :            137 :         pubinfo = findPublicationByOid(pnpubid);
                               4723         [ -  + ]:            137 :         if (pubinfo == NULL)
 1410 akapila@postgresql.o     4724                 :UBC           0 :             continue;
 1410 akapila@postgresql.o     4725                 :CBC         137 :         nspinfo = findNamespaceByOid(pnnspid);
                               4726         [ -  + ]:            137 :         if (nspinfo == NULL)
 1410 akapila@postgresql.o     4727                 :UBC           0 :             continue;
                               4728                 :                : 
                               4729                 :                :         /* OK, make a DumpableObject for this relationship */
 1397 akapila@postgresql.o     4730                 :CBC         137 :         pubsinfo[j].dobj.objType = DO_PUBLICATION_TABLE_IN_SCHEMA;
 1410                          4731                 :            137 :         pubsinfo[j].dobj.catId.tableoid =
                               4732                 :            137 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4733                 :            137 :         pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4734                 :            137 :         AssignDumpId(&pubsinfo[j].dobj);
                               4735                 :            137 :         pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
                               4736                 :            137 :         pubsinfo[j].dobj.name = nspinfo->dobj.name;
                               4737                 :            137 :         pubsinfo[j].publication = pubinfo;
                               4738                 :            137 :         pubsinfo[j].pubschema = nspinfo;
                               4739                 :                : 
                               4740                 :                :         /* Decide whether we want to dump it */
                               4741                 :            137 :         selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
                               4742                 :                : 
                               4743                 :            137 :         j++;
                               4744                 :                :     }
                               4745                 :                : 
                               4746                 :            185 :     PQclear(res);
                               4747                 :            185 :     destroyPQExpBuffer(query);
                               4748                 :                : }
                               4749                 :                : 
                               4750                 :                : /*
                               4751                 :                :  * getPublicationTables
                               4752                 :                :  *    get information about publication membership for dumpable tables.
                               4753                 :                :  */
                               4754                 :                : void
 3152 peter_e@gmx.net          4755                 :            185 : getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
                               4756                 :                : {
                               4757                 :                :     PQExpBuffer query;
                               4758                 :                :     PGresult   *res;
                               4759                 :                :     PublicationRelInfo *pubrinfo;
 2538 michael@paquier.xyz      4760                 :            185 :     DumpOptions *dopt = fout->dopt;
                               4761                 :                :     int         i_tableoid;
                               4762                 :                :     int         i_oid;
                               4763                 :                :     int         i_prpubid;
                               4764                 :                :     int         i_prrelid;
                               4765                 :                :     int         i_prrelqual;
                               4766                 :                :     int         i_prattrs;
                               4767                 :                :     int         i,
                               4768                 :                :                 j,
                               4769                 :                :                 ntups;
                               4770                 :                : 
                               4771   [ +  -  -  + ]:            185 :     if (dopt->no_publications || fout->remoteVersion < 100000)
 3152 peter_e@gmx.net          4772                 :UBC           0 :         return;
                               4773                 :                : 
 3152 peter_e@gmx.net          4774                 :CBC         185 :     query = createPQExpBuffer();
                               4775                 :                : 
                               4776                 :                :     /* Collect all publication membership info. */
 1292 akapila@postgresql.o     4777         [ +  - ]:            185 :     if (fout->remoteVersion >= 150000)
                               4778                 :            185 :         appendPQExpBufferStr(query,
                               4779                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4780                 :                :                              "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
                               4781                 :                :                              "(CASE\n"
                               4782                 :                :                              "  WHEN pr.prattrs IS NOT NULL THEN\n"
                               4783                 :                :                              "    (SELECT array_agg(attname)\n"
                               4784                 :                :                              "       FROM\n"
                               4785                 :                :                              "         pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
                               4786                 :                :                              "         pg_catalog.pg_attribute\n"
                               4787                 :                :                              "      WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
                               4788                 :                :                              "  ELSE NULL END) prattrs "
                               4789                 :                :                              "FROM pg_catalog.pg_publication_rel pr");
                               4790                 :                :     else
 1292 akapila@postgresql.o     4791                 :UBC           0 :         appendPQExpBufferStr(query,
                               4792                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4793                 :                :                              "NULL AS prrelqual, NULL AS prattrs "
                               4794                 :                :                              "FROM pg_catalog.pg_publication_rel");
 1696 tgl@sss.pgh.pa.us        4795                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4796                 :                : 
                               4797                 :            185 :     ntups = PQntuples(res);
                               4798                 :                : 
                               4799                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               4800                 :            185 :     i_oid = PQfnumber(res, "oid");
                               4801                 :            185 :     i_prpubid = PQfnumber(res, "prpubid");
                               4802                 :            185 :     i_prrelid = PQfnumber(res, "prrelid");
 1292 akapila@postgresql.o     4803                 :            185 :     i_prrelqual = PQfnumber(res, "prrelqual");
 1260 tomas.vondra@postgre     4804                 :            185 :     i_prattrs = PQfnumber(res, "prattrs");
                               4805                 :                : 
                               4806                 :                :     /* this allocation may be more than we need */
 1696 tgl@sss.pgh.pa.us        4807                 :            185 :     pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
                               4808                 :            185 :     j = 0;
                               4809                 :                : 
                               4810         [ +  + ]:            577 :     for (i = 0; i < ntups; i++)
                               4811                 :                :     {
                               4812                 :            392 :         Oid         prpubid = atooid(PQgetvalue(res, i, i_prpubid));
                               4813                 :            392 :         Oid         prrelid = atooid(PQgetvalue(res, i, i_prrelid));
                               4814                 :                :         PublicationInfo *pubinfo;
                               4815                 :                :         TableInfo  *tbinfo;
                               4816                 :                : 
                               4817                 :                :         /*
                               4818                 :                :          * Ignore any entries for which we aren't interested in either the
                               4819                 :                :          * publication or the rel.
                               4820                 :                :          */
                               4821                 :            392 :         pubinfo = findPublicationByOid(prpubid);
                               4822         [ -  + ]:            392 :         if (pubinfo == NULL)
 1696 tgl@sss.pgh.pa.us        4823                 :UBC           0 :             continue;
 1696 tgl@sss.pgh.pa.us        4824                 :CBC         392 :         tbinfo = findTableByOid(prrelid);
                               4825         [ -  + ]:            392 :         if (tbinfo == NULL)
 3152 peter_e@gmx.net          4826                 :UBC           0 :             continue;
                               4827                 :                : 
                               4828                 :                :         /* OK, make a DumpableObject for this relationship */
 1696 tgl@sss.pgh.pa.us        4829                 :CBC         392 :         pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
                               4830                 :            392 :         pubrinfo[j].dobj.catId.tableoid =
                               4831                 :            392 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4832                 :            392 :         pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4833                 :            392 :         AssignDumpId(&pubrinfo[j].dobj);
                               4834                 :            392 :         pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4835                 :            392 :         pubrinfo[j].dobj.name = tbinfo->dobj.name;
                               4836                 :            392 :         pubrinfo[j].publication = pubinfo;
                               4837                 :            392 :         pubrinfo[j].pubtable = tbinfo;
 1292 akapila@postgresql.o     4838         [ +  + ]:            392 :         if (PQgetisnull(res, i, i_prrelqual))
                               4839                 :            218 :             pubrinfo[j].pubrelqual = NULL;
                               4840                 :                :         else
                               4841                 :            174 :             pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
                               4842                 :                : 
 1260 tomas.vondra@postgre     4843         [ +  + ]:            392 :         if (!PQgetisnull(res, i, i_prattrs))
                               4844                 :                :         {
                               4845                 :                :             char      **attnames;
                               4846                 :                :             int         nattnames;
                               4847                 :                :             PQExpBuffer attribs;
                               4848                 :                : 
                               4849         [ -  + ]:            123 :             if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
                               4850                 :                :                               &attnames, &nattnames))
 1247 tgl@sss.pgh.pa.us        4851                 :UBC           0 :                 pg_fatal("could not parse %s array", "prattrs");
 1260 tomas.vondra@postgre     4852                 :CBC         123 :             attribs = createPQExpBuffer();
                               4853         [ +  + ]:            355 :             for (int k = 0; k < nattnames; k++)
                               4854                 :                :             {
                               4855         [ +  + ]:            232 :                 if (k > 0)
                               4856                 :            109 :                     appendPQExpBufferStr(attribs, ", ");
                               4857                 :                : 
                               4858                 :            232 :                 appendPQExpBufferStr(attribs, fmtId(attnames[k]));
                               4859                 :                :             }
                               4860                 :            123 :             pubrinfo[j].pubrattrs = attribs->data;
  206 tgl@sss.pgh.pa.us        4861                 :            123 :             free(attribs);      /* but not attribs->data */
                               4862                 :            123 :             free(attnames);
                               4863                 :                :         }
                               4864                 :                :         else
 1260 tomas.vondra@postgre     4865                 :            269 :             pubrinfo[j].pubrattrs = NULL;
                               4866                 :                : 
                               4867                 :                :         /* Decide whether we want to dump it */
 1410 akapila@postgresql.o     4868                 :            392 :         selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
                               4869                 :                : 
 1696 tgl@sss.pgh.pa.us        4870                 :            392 :         j++;
                               4871                 :                :     }
                               4872                 :                : 
                               4873                 :            185 :     PQclear(res);
 3152 peter_e@gmx.net          4874                 :            185 :     destroyPQExpBuffer(query);
                               4875                 :                : }
                               4876                 :                : 
                               4877                 :                : /*
                               4878                 :                :  * dumpPublicationNamespace
                               4879                 :                :  *    dump the definition of the given publication schema mapping.
                               4880                 :                :  */
                               4881                 :                : static void
 1410 akapila@postgresql.o     4882                 :            111 : dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
                               4883                 :                : {
 1346 tgl@sss.pgh.pa.us        4884                 :            111 :     DumpOptions *dopt = fout->dopt;
 1410 akapila@postgresql.o     4885                 :            111 :     NamespaceInfo *schemainfo = pubsinfo->pubschema;
                               4886                 :            111 :     PublicationInfo *pubinfo = pubsinfo->publication;
                               4887                 :                :     PQExpBuffer query;
                               4888                 :                :     char       *tag;
                               4889                 :                : 
                               4890                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     4891         [ +  + ]:            111 :     if (!dopt->dumpSchema)
 1410 akapila@postgresql.o     4892                 :             12 :         return;
                               4893                 :                : 
                               4894                 :             99 :     tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
                               4895                 :                : 
                               4896                 :             99 :     query = createPQExpBuffer();
                               4897                 :                : 
                               4898                 :             99 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
 1080 alvherre@alvh.no-ip.     4899                 :             99 :     appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
                               4900                 :                : 
                               4901                 :                :     /*
                               4902                 :                :      * There is no point in creating drop query as the drop is done by schema
                               4903                 :                :      * drop.
                               4904                 :                :      */
 1346 tgl@sss.pgh.pa.us        4905         [ +  - ]:             99 :     if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4906                 :             99 :         ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
                               4907                 :             99 :                      ARCHIVE_OPTS(.tag = tag,
                               4908                 :                :                                   .namespace = schemainfo->dobj.name,
                               4909                 :                :                                   .owner = pubinfo->rolname,
                               4910                 :                :                                   .description = "PUBLICATION TABLES IN SCHEMA",
                               4911                 :                :                                   .section = SECTION_POST_DATA,
                               4912                 :                :                                   .createStmt = query->data));
                               4913                 :                : 
                               4914                 :                :     /* These objects can't currently have comments or seclabels */
                               4915                 :                : 
 1410 akapila@postgresql.o     4916                 :             99 :     free(tag);
                               4917                 :             99 :     destroyPQExpBuffer(query);
                               4918                 :                : }
                               4919                 :                : 
                               4920                 :                : /*
                               4921                 :                :  * dumpPublicationTable
                               4922                 :                :  *    dump the definition of the given publication table mapping
                               4923                 :                :  */
                               4924                 :                : static void
 1669 peter@eisentraut.org     4925                 :            326 : dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
                               4926                 :                : {
 1346 tgl@sss.pgh.pa.us        4927                 :            326 :     DumpOptions *dopt = fout->dopt;
 1696                          4928                 :            326 :     PublicationInfo *pubinfo = pubrinfo->publication;
 3152 peter_e@gmx.net          4929                 :            326 :     TableInfo  *tbinfo = pubrinfo->pubtable;
                               4930                 :                :     PQExpBuffer query;
                               4931                 :                :     char       *tag;
                               4932                 :                : 
                               4933                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     4934         [ +  + ]:            326 :     if (!dopt->dumpSchema)
 1346 tgl@sss.pgh.pa.us        4935                 :             42 :         return;
                               4936                 :                : 
 1696                          4937                 :            284 :     tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
                               4938                 :                : 
 3152 peter_e@gmx.net          4939                 :            284 :     query = createPQExpBuffer();
                               4940                 :                : 
 1248 tomas.vondra@postgre     4941                 :            284 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
                               4942                 :            284 :                       fmtId(pubinfo->dobj.name));
 1292 akapila@postgresql.o     4943                 :            284 :     appendPQExpBuffer(query, " %s",
 2749 tgl@sss.pgh.pa.us        4944                 :            284 :                       fmtQualifiedDumpable(tbinfo));
                               4945                 :                : 
 1260 tomas.vondra@postgre     4946         [ +  + ]:            284 :     if (pubrinfo->pubrattrs)
                               4947                 :             89 :         appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
                               4948                 :                : 
 1292 akapila@postgresql.o     4949         [ +  + ]:            284 :     if (pubrinfo->pubrelqual)
                               4950                 :                :     {
                               4951                 :                :         /*
                               4952                 :                :          * It's necessary to add parentheses around the expression because
                               4953                 :                :          * pg_get_expr won't supply the parentheses for things like WHERE
                               4954                 :                :          * TRUE.
                               4955                 :                :          */
                               4956                 :            126 :         appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
                               4957                 :                :     }
                               4958                 :            284 :     appendPQExpBufferStr(query, ";\n");
                               4959                 :                : 
                               4960                 :                :     /*
                               4961                 :                :      * There is no point in creating a drop query as the drop is done by table
                               4962                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               4963                 :                :      * Although this object doesn't really have ownership as such, set the
                               4964                 :                :      * owner field anyway to ensure that the command is run by the correct
                               4965                 :                :      * role at restore time.
                               4966                 :                :      */
 1370 tgl@sss.pgh.pa.us        4967         [ +  - ]:            284 :     if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4968                 :            284 :         ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
                               4969                 :            284 :                      ARCHIVE_OPTS(.tag = tag,
                               4970                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               4971                 :                :                                   .owner = pubinfo->rolname,
                               4972                 :                :                                   .description = "PUBLICATION TABLE",
                               4973                 :                :                                   .section = SECTION_POST_DATA,
                               4974                 :                :                                   .createStmt = query->data));
                               4975                 :                : 
                               4976                 :                :     /* These objects can't currently have comments or seclabels */
                               4977                 :                : 
 3152 peter_e@gmx.net          4978                 :            284 :     free(tag);
                               4979                 :            284 :     destroyPQExpBuffer(query);
                               4980                 :                : }
                               4981                 :                : 
                               4982                 :                : /*
                               4983                 :                :  * Is the currently connected user a superuser?
                               4984                 :                :  */
                               4985                 :                : static bool
 3070                          4986                 :            185 : is_superuser(Archive *fout)
                               4987                 :                : {
                               4988                 :            185 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                               4989                 :                :     const char *val;
                               4990                 :                : 
                               4991                 :            185 :     val = PQparameterStatus(AH->connection, "is_superuser");
                               4992                 :                : 
                               4993   [ +  -  +  + ]:            185 :     if (val && strcmp(val, "on") == 0)
                               4994                 :            182 :         return true;
                               4995                 :                : 
                               4996                 :              3 :     return false;
                               4997                 :                : }
                               4998                 :                : 
                               4999                 :                : /*
                               5000                 :                :  * Set the given value to restrict_nonsystem_relation_kind value. Since
                               5001                 :                :  * restrict_nonsystem_relation_kind is introduced in minor version releases,
                               5002                 :                :  * the setting query is effective only where available.
                               5003                 :                :  */
                               5004                 :                : static void
  397 msawada@postgresql.o     5005                 :            221 : set_restrict_relation_kind(Archive *AH, const char *value)
                               5006                 :                : {
                               5007                 :            221 :     PQExpBuffer query = createPQExpBuffer();
                               5008                 :                :     PGresult   *res;
                               5009                 :                : 
                               5010                 :            221 :     appendPQExpBuffer(query,
                               5011                 :                :                       "SELECT set_config(name, '%s', false) "
                               5012                 :                :                       "FROM pg_settings "
                               5013                 :                :                       "WHERE name = 'restrict_nonsystem_relation_kind'",
                               5014                 :                :                       value);
                               5015                 :            221 :     res = ExecuteSqlQuery(AH, query->data, PGRES_TUPLES_OK);
                               5016                 :                : 
                               5017                 :            221 :     PQclear(res);
                               5018                 :            221 :     destroyPQExpBuffer(query);
                               5019                 :            221 : }
                               5020                 :                : 
                               5021                 :                : /*
                               5022                 :                :  * getSubscriptions
                               5023                 :                :  *    get information about subscriptions
                               5024                 :                :  */
                               5025                 :                : void
 3152 peter_e@gmx.net          5026                 :            185 : getSubscriptions(Archive *fout)
                               5027                 :                : {
 3042                          5028                 :            185 :     DumpOptions *dopt = fout->dopt;
                               5029                 :                :     PQExpBuffer query;
                               5030                 :                :     PGresult   *res;
                               5031                 :                :     SubscriptionInfo *subinfo;
                               5032                 :                :     int         i_tableoid;
                               5033                 :                :     int         i_oid;
                               5034                 :                :     int         i_subname;
                               5035                 :                :     int         i_subowner;
                               5036                 :                :     int         i_subbinary;
                               5037                 :                :     int         i_substream;
                               5038                 :                :     int         i_subtwophasestate;
                               5039                 :                :     int         i_subdisableonerr;
                               5040                 :                :     int         i_subpasswordrequired;
                               5041                 :                :     int         i_subrunasowner;
                               5042                 :                :     int         i_subconninfo;
                               5043                 :                :     int         i_subslotname;
                               5044                 :                :     int         i_subsynccommit;
                               5045                 :                :     int         i_subpublications;
                               5046                 :                :     int         i_suborigin;
                               5047                 :                :     int         i_suboriginremotelsn;
                               5048                 :                :     int         i_subenabled;
                               5049                 :                :     int         i_subfailover;
                               5050                 :                :     int         i_subretaindeadtuples;
                               5051                 :                :     int         i_submaxretention;
                               5052                 :                :     int         i,
                               5053                 :                :                 ntups;
                               5054                 :                : 
                               5055   [ +  -  -  + ]:            185 :     if (dopt->no_subscriptions || fout->remoteVersion < 100000)
 3070 peter_e@gmx.net          5056                 :UBC           0 :         return;
                               5057                 :                : 
 3070 peter_e@gmx.net          5058         [ +  + ]:CBC         185 :     if (!is_superuser(fout))
                               5059                 :                :     {
                               5060                 :                :         int         n;
                               5061                 :                : 
                               5062                 :              3 :         res = ExecuteSqlQuery(fout,
                               5063                 :                :                               "SELECT count(*) FROM pg_subscription "
                               5064                 :                :                               "WHERE subdbid = (SELECT oid FROM pg_database"
                               5065                 :                :                               "                 WHERE datname = current_database())",
                               5066                 :                :                               PGRES_TUPLES_OK);
                               5067                 :              3 :         n = atoi(PQgetvalue(res, 0, 0));
                               5068         [ +  + ]:              3 :         if (n > 0)
 2350 peter@eisentraut.org     5069                 :              2 :             pg_log_warning("subscriptions not dumped because current user is not a superuser");
 3070 peter_e@gmx.net          5070                 :              3 :         PQclear(res);
 3152                          5071                 :              3 :         return;
                               5072                 :                :     }
                               5073                 :                : 
                               5074                 :            182 :     query = createPQExpBuffer();
                               5075                 :                : 
                               5076                 :                :     /* Get the subscriptions in current database. */
 1096 drowley@postgresql.o     5077                 :            182 :     appendPQExpBufferStr(query,
                               5078                 :                :                          "SELECT s.tableoid, s.oid, s.subname,\n"
                               5079                 :                :                          " s.subowner,\n"
                               5080                 :                :                          " s.subconninfo, s.subslotname, s.subsynccommit,\n"
                               5081                 :                :                          " s.subpublications,\n");
                               5082                 :                : 
 1876 tgl@sss.pgh.pa.us        5083         [ +  - ]:            182 :     if (fout->remoteVersion >= 140000)
 1787 drowley@postgresql.o     5084                 :            182 :         appendPQExpBufferStr(query, " s.subbinary,\n");
                               5085                 :                :     else
 1787 drowley@postgresql.o     5086                 :UBC           0 :         appendPQExpBufferStr(query, " false AS subbinary,\n");
                               5087                 :                : 
 1829 akapila@postgresql.o     5088         [ +  - ]:CBC         182 :     if (fout->remoteVersion >= 140000)
 1515                          5089                 :            182 :         appendPQExpBufferStr(query, " s.substream,\n");
                               5090                 :                :     else
  971 akapila@postgresql.o     5091                 :UBC           0 :         appendPQExpBufferStr(query, " 'f' AS substream,\n");
                               5092                 :                : 
 1515 akapila@postgresql.o     5093         [ +  - ]:CBC         182 :     if (fout->remoteVersion >= 150000)
 1272                          5094                 :            182 :         appendPQExpBufferStr(query,
                               5095                 :                :                              " s.subtwophasestate,\n"
                               5096                 :                :                              " s.subdisableonerr,\n");
                               5097                 :                :     else
 1515 akapila@postgresql.o     5098                 :UBC           0 :         appendPQExpBuffer(query,
                               5099                 :                :                           " '%c' AS subtwophasestate,\n"
                               5100                 :                :                           " false AS subdisableonerr,\n",
                               5101                 :                :                           LOGICALREP_TWOPHASE_STATE_DISABLED);
                               5102                 :                : 
 1143 akapila@postgresql.o     5103         [ +  - ]:CBC         182 :     if (fout->remoteVersion >= 160000)
  891 rhaas@postgresql.org     5104                 :            182 :         appendPQExpBufferStr(query,
                               5105                 :                :                              " s.subpasswordrequired,\n"
                               5106                 :                :                              " s.subrunasowner,\n"
                               5107                 :                :                              " s.suborigin,\n");
                               5108                 :                :     else
  891 rhaas@postgresql.org     5109                 :UBC           0 :         appendPQExpBuffer(query,
                               5110                 :                :                           " 't' AS subpasswordrequired,\n"
                               5111                 :                :                           " 't' AS subrunasowner,\n"
                               5112                 :                :                           " '%s' AS suborigin,\n",
                               5113                 :                :                           LOGICALREP_ORIGIN_ANY);
                               5114                 :                : 
  613 akapila@postgresql.o     5115   [ +  +  +  - ]:CBC         182 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5116                 :             36 :         appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
                               5117                 :                :                              " s.subenabled,\n");
                               5118                 :                :     else
                               5119                 :            146 :         appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
                               5120                 :                :                              " false AS subenabled,\n");
                               5121                 :                : 
  501                          5122         [ +  - ]:            182 :     if (fout->remoteVersion >= 170000)
                               5123                 :            182 :         appendPQExpBufferStr(query,
                               5124                 :                :                              " s.subfailover,\n");
                               5125                 :                :     else
  141 drowley@postgresql.o     5126                 :UNC           0 :         appendPQExpBufferStr(query,
                               5127                 :                :                              " false AS subfailover,\n");
                               5128                 :                : 
   45 akapila@postgresql.o     5129         [ +  - ]:GNC         182 :     if (fout->remoteVersion >= 190000)
                               5130                 :            182 :         appendPQExpBufferStr(query,
                               5131                 :                :                              " s.subretaindeadtuples,\n");
                               5132                 :                :     else
   45 akapila@postgresql.o     5133                 :UBC           0 :         appendPQExpBufferStr(query,
                               5134                 :                :                              " false AS subretaindeadtuples,\n");
                               5135                 :                : 
    4 akapila@postgresql.o     5136         [ +  - ]:GNC         182 :     if (fout->remoteVersion >= 190000)
                               5137                 :            182 :         appendPQExpBufferStr(query,
                               5138                 :                :                              " s.submaxretention\n");
                               5139                 :                :     else
    4 akapila@postgresql.o     5140                 :UNC           0 :         appendPQExpBuffer(query,
                               5141                 :                :                           " 0 AS submaxretention\n");
                               5142                 :                : 
  613 akapila@postgresql.o     5143                 :CBC         182 :     appendPQExpBufferStr(query,
                               5144                 :                :                          "FROM pg_subscription s\n");
                               5145                 :                : 
                               5146   [ +  +  +  - ]:            182 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5147                 :             36 :         appendPQExpBufferStr(query,
                               5148                 :                :                              "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
                               5149                 :                :                              "    ON o.external_id = 'pg_' || s.oid::text \n");
                               5150                 :                : 
 1787 drowley@postgresql.o     5151                 :            182 :     appendPQExpBufferStr(query,
                               5152                 :                :                          "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
                               5153                 :                :                          "                   WHERE datname = current_database())");
                               5154                 :                : 
 3152 peter_e@gmx.net          5155                 :            182 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5156                 :                : 
                               5157                 :            182 :     ntups = PQntuples(res);
                               5158                 :                : 
                               5159                 :                :     /*
                               5160                 :                :      * Get subscription fields. We don't include subskiplsn in the dump as
                               5161                 :                :      * after restoring the dump this value may no longer be relevant.
                               5162                 :                :      */
                               5163                 :            182 :     i_tableoid = PQfnumber(res, "tableoid");
                               5164                 :            182 :     i_oid = PQfnumber(res, "oid");
                               5165                 :            182 :     i_subname = PQfnumber(res, "subname");
 1345 tgl@sss.pgh.pa.us        5166                 :            182 :     i_subowner = PQfnumber(res, "subowner");
  277 michael@paquier.xyz      5167                 :            182 :     i_subenabled = PQfnumber(res, "subenabled");
 1876 tgl@sss.pgh.pa.us        5168                 :            182 :     i_subbinary = PQfnumber(res, "subbinary");
 1829 akapila@postgresql.o     5169                 :            182 :     i_substream = PQfnumber(res, "substream");
 1515                          5170                 :            182 :     i_subtwophasestate = PQfnumber(res, "subtwophasestate");
 1272                          5171                 :            182 :     i_subdisableonerr = PQfnumber(res, "subdisableonerr");
  891 rhaas@postgresql.org     5172                 :            182 :     i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
  678 tgl@sss.pgh.pa.us        5173                 :            182 :     i_subrunasowner = PQfnumber(res, "subrunasowner");
  277 michael@paquier.xyz      5174                 :            182 :     i_subfailover = PQfnumber(res, "subfailover");
   45 akapila@postgresql.o     5175                 :GNC         182 :     i_subretaindeadtuples = PQfnumber(res, "subretaindeadtuples");
    4                          5176                 :            182 :     i_submaxretention = PQfnumber(res, "submaxretention");
  678 tgl@sss.pgh.pa.us        5177                 :CBC         182 :     i_subconninfo = PQfnumber(res, "subconninfo");
                               5178                 :            182 :     i_subslotname = PQfnumber(res, "subslotname");
                               5179                 :            182 :     i_subsynccommit = PQfnumber(res, "subsynccommit");
                               5180                 :            182 :     i_subpublications = PQfnumber(res, "subpublications");
                               5181                 :            182 :     i_suborigin = PQfnumber(res, "suborigin");
  613 akapila@postgresql.o     5182                 :            182 :     i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
                               5183                 :                : 
 3152 peter_e@gmx.net          5184                 :            182 :     subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
                               5185                 :                : 
                               5186         [ +  + ]:            331 :     for (i = 0; i < ntups; i++)
                               5187                 :                :     {
                               5188                 :            149 :         subinfo[i].dobj.objType = DO_SUBSCRIPTION;
                               5189                 :            149 :         subinfo[i].dobj.catId.tableoid =
                               5190                 :            149 :             atooid(PQgetvalue(res, i, i_tableoid));
                               5191                 :            149 :         subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5192                 :            149 :         AssignDumpId(&subinfo[i].dobj);
                               5193                 :            149 :         subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
 1345 tgl@sss.pgh.pa.us        5194                 :            149 :         subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
                               5195                 :                : 
  277 michael@paquier.xyz      5196                 :            149 :         subinfo[i].subenabled =
                               5197                 :            149 :             (strcmp(PQgetvalue(res, i, i_subenabled), "t") == 0);
 1876 tgl@sss.pgh.pa.us        5198                 :            149 :         subinfo[i].subbinary =
  277 michael@paquier.xyz      5199                 :            149 :             (strcmp(PQgetvalue(res, i, i_subbinary), "t") == 0);
                               5200                 :            149 :         subinfo[i].substream = *(PQgetvalue(res, i, i_substream));
                               5201                 :            149 :         subinfo[i].subtwophasestate = *(PQgetvalue(res, i, i_subtwophasestate));
 1272 akapila@postgresql.o     5202                 :            149 :         subinfo[i].subdisableonerr =
  277 michael@paquier.xyz      5203                 :            149 :             (strcmp(PQgetvalue(res, i, i_subdisableonerr), "t") == 0);
  891 rhaas@postgresql.org     5204                 :            149 :         subinfo[i].subpasswordrequired =
  277 michael@paquier.xyz      5205                 :            149 :             (strcmp(PQgetvalue(res, i, i_subpasswordrequired), "t") == 0);
  678 tgl@sss.pgh.pa.us        5206                 :            149 :         subinfo[i].subrunasowner =
  277 michael@paquier.xyz      5207                 :            149 :             (strcmp(PQgetvalue(res, i, i_subrunasowner), "t") == 0);
                               5208                 :            149 :         subinfo[i].subfailover =
                               5209                 :            149 :             (strcmp(PQgetvalue(res, i, i_subfailover), "t") == 0);
   45 akapila@postgresql.o     5210                 :GNC         149 :         subinfo[i].subretaindeadtuples =
                               5211                 :            149 :             (strcmp(PQgetvalue(res, i, i_subretaindeadtuples), "t") == 0);
    4                          5212                 :            149 :         subinfo[i].submaxretention =
                               5213                 :            149 :             atoi(PQgetvalue(res, i, i_submaxretention));
  678 tgl@sss.pgh.pa.us        5214                 :CBC         298 :         subinfo[i].subconninfo =
                               5215                 :            149 :             pg_strdup(PQgetvalue(res, i, i_subconninfo));
                               5216         [ -  + ]:            149 :         if (PQgetisnull(res, i, i_subslotname))
  678 tgl@sss.pgh.pa.us        5217                 :UBC           0 :             subinfo[i].subslotname = NULL;
                               5218                 :                :         else
  678 tgl@sss.pgh.pa.us        5219                 :CBC         149 :             subinfo[i].subslotname =
                               5220                 :            149 :                 pg_strdup(PQgetvalue(res, i, i_subslotname));
                               5221                 :            298 :         subinfo[i].subsynccommit =
                               5222                 :            149 :             pg_strdup(PQgetvalue(res, i, i_subsynccommit));
                               5223                 :            298 :         subinfo[i].subpublications =
                               5224                 :            149 :             pg_strdup(PQgetvalue(res, i, i_subpublications));
                               5225                 :            149 :         subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
  613 akapila@postgresql.o     5226         [ +  + ]:            149 :         if (PQgetisnull(res, i, i_suboriginremotelsn))
                               5227                 :            148 :             subinfo[i].suboriginremotelsn = NULL;
                               5228                 :                :         else
                               5229                 :              1 :             subinfo[i].suboriginremotelsn =
                               5230                 :              1 :                 pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
                               5231                 :                : 
                               5232                 :                :         /* Decide whether we want to dump it */
 3070 peter_e@gmx.net          5233                 :            149 :         selectDumpableObject(&(subinfo[i].dobj), fout);
                               5234                 :                :     }
 3152                          5235                 :            182 :     PQclear(res);
                               5236                 :                : 
                               5237                 :            182 :     destroyPQExpBuffer(query);
                               5238                 :                : }
                               5239                 :                : 
                               5240                 :                : /*
                               5241                 :                :  * getSubscriptionTables
                               5242                 :                :  *    Get information about subscription membership for dumpable tables. This
                               5243                 :                :  *    will be used only in binary-upgrade mode for PG17 or later versions.
                               5244                 :                :  */
                               5245                 :                : void
  613 akapila@postgresql.o     5246                 :            185 : getSubscriptionTables(Archive *fout)
                               5247                 :                : {
                               5248                 :            185 :     DumpOptions *dopt = fout->dopt;
                               5249                 :            185 :     SubscriptionInfo *subinfo = NULL;
                               5250                 :                :     SubRelInfo *subrinfo;
                               5251                 :                :     PGresult   *res;
                               5252                 :                :     int         i_srsubid;
                               5253                 :                :     int         i_srrelid;
                               5254                 :                :     int         i_srsubstate;
                               5255                 :                :     int         i_srsublsn;
                               5256                 :                :     int         ntups;
                               5257                 :            185 :     Oid         last_srsubid = InvalidOid;
                               5258                 :                : 
                               5259   [ +  -  +  + ]:            185 :     if (dopt->no_subscriptions || !dopt->binary_upgrade ||
                               5260         [ -  + ]:             36 :         fout->remoteVersion < 170000)
                               5261                 :            149 :         return;
                               5262                 :                : 
                               5263                 :             36 :     res = ExecuteSqlQuery(fout,
                               5264                 :                :                           "SELECT srsubid, srrelid, srsubstate, srsublsn "
                               5265                 :                :                           "FROM pg_catalog.pg_subscription_rel "
                               5266                 :                :                           "ORDER BY srsubid",
                               5267                 :                :                           PGRES_TUPLES_OK);
                               5268                 :             36 :     ntups = PQntuples(res);
                               5269         [ +  + ]:             36 :     if (ntups == 0)
                               5270                 :             35 :         goto cleanup;
                               5271                 :                : 
                               5272                 :                :     /* Get pg_subscription_rel attributes */
                               5273                 :              1 :     i_srsubid = PQfnumber(res, "srsubid");
                               5274                 :              1 :     i_srrelid = PQfnumber(res, "srrelid");
                               5275                 :              1 :     i_srsubstate = PQfnumber(res, "srsubstate");
                               5276                 :              1 :     i_srsublsn = PQfnumber(res, "srsublsn");
                               5277                 :                : 
                               5278                 :              1 :     subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
                               5279         [ +  + ]:              3 :     for (int i = 0; i < ntups; i++)
                               5280                 :                :     {
                               5281                 :              2 :         Oid         cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
                               5282                 :              2 :         Oid         relid = atooid(PQgetvalue(res, i, i_srrelid));
                               5283                 :                :         TableInfo  *tblinfo;
                               5284                 :                : 
                               5285                 :                :         /*
                               5286                 :                :          * If we switched to a new subscription, check if the subscription
                               5287                 :                :          * exists.
                               5288                 :                :          */
                               5289         [ +  - ]:              2 :         if (cur_srsubid != last_srsubid)
                               5290                 :                :         {
                               5291                 :              2 :             subinfo = findSubscriptionByOid(cur_srsubid);
                               5292         [ -  + ]:              2 :             if (subinfo == NULL)
  613 akapila@postgresql.o     5293                 :UBC           0 :                 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
                               5294                 :                : 
  613 akapila@postgresql.o     5295                 :CBC           2 :             last_srsubid = cur_srsubid;
                               5296                 :                :         }
                               5297                 :                : 
                               5298                 :              2 :         tblinfo = findTableByOid(relid);
                               5299         [ -  + ]:              2 :         if (tblinfo == NULL)
  613 akapila@postgresql.o     5300                 :UBC           0 :             pg_fatal("failed sanity check, table with OID %u not found",
                               5301                 :                :                      relid);
                               5302                 :                : 
                               5303                 :                :         /* OK, make a DumpableObject for this relationship */
  613 akapila@postgresql.o     5304                 :CBC           2 :         subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
                               5305                 :              2 :         subrinfo[i].dobj.catId.tableoid = relid;
                               5306                 :              2 :         subrinfo[i].dobj.catId.oid = cur_srsubid;
                               5307                 :              2 :         AssignDumpId(&subrinfo[i].dobj);
                               5308                 :              2 :         subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
                               5309                 :              2 :         subrinfo[i].tblinfo = tblinfo;
                               5310                 :              2 :         subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
                               5311         [ +  + ]:              2 :         if (PQgetisnull(res, i, i_srsublsn))
                               5312                 :              1 :             subrinfo[i].srsublsn = NULL;
                               5313                 :                :         else
                               5314                 :              1 :             subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
                               5315                 :                : 
                               5316                 :              2 :         subrinfo[i].subinfo = subinfo;
                               5317                 :                : 
                               5318                 :                :         /* Decide whether we want to dump it */
                               5319                 :              2 :         selectDumpableObject(&(subrinfo[i].dobj), fout);
                               5320                 :                :     }
                               5321                 :                : 
                               5322                 :              1 : cleanup:
                               5323                 :             36 :     PQclear(res);
                               5324                 :                : }
                               5325                 :                : 
                               5326                 :                : /*
                               5327                 :                :  * dumpSubscriptionTable
                               5328                 :                :  *    Dump the definition of the given subscription table mapping. This will be
                               5329                 :                :  *    used only in binary-upgrade mode for PG17 or later versions.
                               5330                 :                :  */
                               5331                 :                : static void
                               5332                 :              2 : dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
                               5333                 :                : {
                               5334                 :              2 :     DumpOptions *dopt = fout->dopt;
                               5335                 :              2 :     SubscriptionInfo *subinfo = subrinfo->subinfo;
                               5336                 :                :     PQExpBuffer query;
                               5337                 :                :     char       *tag;
                               5338                 :                : 
                               5339                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     5340         [ -  + ]:              2 :     if (!dopt->dumpSchema)
  613 akapila@postgresql.o     5341                 :UBC           0 :         return;
                               5342                 :                : 
  613 akapila@postgresql.o     5343   [ +  -  +  - ]:CBC           2 :     Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
                               5344                 :                : 
                               5345                 :              2 :     tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
                               5346                 :                : 
                               5347                 :              2 :     query = createPQExpBuffer();
                               5348                 :                : 
                               5349         [ +  - ]:              2 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5350                 :                :     {
                               5351                 :                :         /*
                               5352                 :                :          * binary_upgrade_add_sub_rel_state will add the subscription relation
                               5353                 :                :          * to pg_subscription_rel table. This will be used only in
                               5354                 :                :          * binary-upgrade mode.
                               5355                 :                :          */
                               5356                 :              2 :         appendPQExpBufferStr(query,
                               5357                 :                :                              "\n-- For binary upgrade, must preserve the subscriber table.\n");
                               5358                 :              2 :         appendPQExpBufferStr(query,
                               5359                 :                :                              "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
                               5360                 :              2 :         appendStringLiteralAH(query, subrinfo->dobj.name, fout);
                               5361                 :              2 :         appendPQExpBuffer(query,
                               5362                 :                :                           ", %u, '%c'",
                               5363                 :              2 :                           subrinfo->tblinfo->dobj.catId.oid,
                               5364                 :              2 :                           subrinfo->srsubstate);
                               5365                 :                : 
                               5366   [ +  +  +  - ]:              2 :         if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
                               5367                 :              1 :             appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
                               5368                 :                :         else
  141 drowley@postgresql.o     5369                 :              1 :             appendPQExpBufferStr(query, ", NULL");
                               5370                 :                : 
  613 akapila@postgresql.o     5371                 :              2 :         appendPQExpBufferStr(query, ");\n");
                               5372                 :                :     }
                               5373                 :                : 
                               5374                 :                :     /*
                               5375                 :                :      * There is no point in creating a drop query as the drop is done by table
                               5376                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               5377                 :                :      * Although this object doesn't really have ownership as such, set the
                               5378                 :                :      * owner field anyway to ensure that the command is run by the correct
                               5379                 :                :      * role at restore time.
                               5380                 :                :      */
                               5381         [ +  - ]:              2 :     if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5382                 :              2 :         ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
                               5383                 :              2 :                      ARCHIVE_OPTS(.tag = tag,
                               5384                 :                :                                   .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
                               5385                 :                :                                   .owner = subinfo->rolname,
                               5386                 :                :                                   .description = "SUBSCRIPTION TABLE",
                               5387                 :                :                                   .section = SECTION_POST_DATA,
                               5388                 :                :                                   .createStmt = query->data));
                               5389                 :                : 
                               5390                 :                :     /* These objects can't currently have comments or seclabels */
                               5391                 :                : 
                               5392                 :              2 :     free(tag);
                               5393                 :              2 :     destroyPQExpBuffer(query);
                               5394                 :                : }
                               5395                 :                : 
                               5396                 :                : /*
                               5397                 :                :  * dumpSubscription
                               5398                 :                :  *    dump the definition of the given subscription
                               5399                 :                :  */
                               5400                 :                : static void
 1669 peter@eisentraut.org     5401                 :            131 : dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
                               5402                 :                : {
 1346 tgl@sss.pgh.pa.us        5403                 :            131 :     DumpOptions *dopt = fout->dopt;
                               5404                 :                :     PQExpBuffer delq;
                               5405                 :                :     PQExpBuffer query;
                               5406                 :                :     PQExpBuffer publications;
                               5407                 :                :     char       *qsubname;
 3152 peter_e@gmx.net          5408                 :            131 :     char      **pubnames = NULL;
                               5409                 :            131 :     int         npubnames = 0;
                               5410                 :                :     int         i;
                               5411                 :                : 
                               5412                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or     5413         [ +  + ]:            131 :     if (!dopt->dumpSchema)
 1346 tgl@sss.pgh.pa.us        5414                 :             18 :         return;
                               5415                 :                : 
 3152 peter_e@gmx.net          5416                 :            113 :     delq = createPQExpBuffer();
                               5417                 :            113 :     query = createPQExpBuffer();
                               5418                 :                : 
 2749 tgl@sss.pgh.pa.us        5419                 :            113 :     qsubname = pg_strdup(fmtId(subinfo->dobj.name));
                               5420                 :                : 
 3152 peter_e@gmx.net          5421                 :            113 :     appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
                               5422                 :                :                       qsubname);
                               5423                 :                : 
                               5424                 :            113 :     appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
                               5425                 :                :                       qsubname);
                               5426                 :            113 :     appendStringLiteralAH(query, subinfo->subconninfo, fout);
                               5427                 :                : 
                               5428                 :                :     /* Build list of quoted publications and append them to query. */
                               5429         [ -  + ]:            113 :     if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
 1247 tgl@sss.pgh.pa.us        5430                 :UBC           0 :         pg_fatal("could not parse %s array", "subpublications");
                               5431                 :                : 
 3152 peter_e@gmx.net          5432                 :CBC         113 :     publications = createPQExpBuffer();
                               5433         [ +  + ]:            226 :     for (i = 0; i < npubnames; i++)
                               5434                 :                :     {
                               5435         [ -  + ]:            113 :         if (i > 0)
 3152 peter_e@gmx.net          5436                 :UBC           0 :             appendPQExpBufferStr(publications, ", ");
                               5437                 :                : 
 3152 peter_e@gmx.net          5438                 :CBC         113 :         appendPQExpBufferStr(publications, fmtId(pubnames[i]));
                               5439                 :                :     }
                               5440                 :                : 
 3039                          5441                 :            113 :     appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
 3034                          5442         [ +  - ]:            113 :     if (subinfo->subslotname)
                               5443                 :            113 :         appendStringLiteralAH(query, subinfo->subslotname, fout);
                               5444                 :                :     else
 3034 peter_e@gmx.net          5445                 :UBC           0 :         appendPQExpBufferStr(query, "NONE");
                               5446                 :                : 
  277 michael@paquier.xyz      5447         [ -  + ]:CBC         113 :     if (subinfo->subbinary)
 1787 drowley@postgresql.o     5448                 :UBC           0 :         appendPQExpBufferStr(query, ", binary = true");
                               5449                 :                : 
  277 michael@paquier.xyz      5450         [ +  + ]:CBC         113 :     if (subinfo->substream == LOGICALREP_STREAM_ON)
 1787 drowley@postgresql.o     5451                 :             37 :         appendPQExpBufferStr(query, ", streaming = on");
  277 michael@paquier.xyz      5452         [ +  + ]:             76 :     else if (subinfo->substream == LOGICALREP_STREAM_PARALLEL)
  971 akapila@postgresql.o     5453                 :             39 :         appendPQExpBufferStr(query, ", streaming = parallel");
                               5454                 :                :     else
  313                          5455                 :             37 :         appendPQExpBufferStr(query, ", streaming = off");
                               5456                 :                : 
  277 michael@paquier.xyz      5457         [ -  + ]:            113 :     if (subinfo->subtwophasestate != LOGICALREP_TWOPHASE_STATE_DISABLED)
 1515 akapila@postgresql.o     5458                 :UBC           0 :         appendPQExpBufferStr(query, ", two_phase = on");
                               5459                 :                : 
  277 michael@paquier.xyz      5460         [ -  + ]:CBC         113 :     if (subinfo->subdisableonerr)
 1272 akapila@postgresql.o     5461                 :UBC           0 :         appendPQExpBufferStr(query, ", disable_on_error = true");
                               5462                 :                : 
  277 michael@paquier.xyz      5463         [ -  + ]:CBC         113 :     if (!subinfo->subpasswordrequired)
  141 drowley@postgresql.o     5464                 :UBC           0 :         appendPQExpBufferStr(query, ", password_required = false");
                               5465                 :                : 
  277 michael@paquier.xyz      5466         [ -  + ]:CBC         113 :     if (subinfo->subrunasowner)
  678 tgl@sss.pgh.pa.us        5467                 :UBC           0 :         appendPQExpBufferStr(query, ", run_as_owner = true");
                               5468                 :                : 
  277 michael@paquier.xyz      5469         [ +  + ]:CBC         113 :     if (subinfo->subfailover)
  501 akapila@postgresql.o     5470                 :              1 :         appendPQExpBufferStr(query, ", failover = true");
                               5471                 :                : 
   45 akapila@postgresql.o     5472         [ +  + ]:GNC         113 :     if (subinfo->subretaindeadtuples)
                               5473                 :              1 :         appendPQExpBufferStr(query, ", retain_dead_tuples = true");
                               5474                 :                : 
    4                          5475         [ -  + ]:            113 :     if (subinfo->submaxretention)
    4 akapila@postgresql.o     5476                 :UNC           0 :         appendPQExpBuffer(query, ", max_retention_duration = %d", subinfo->submaxretention);
                               5477                 :                : 
 3067 peter_e@gmx.net          5478         [ -  + ]:CBC         113 :     if (strcmp(subinfo->subsynccommit, "off") != 0)
 3039 peter_e@gmx.net          5479                 :UBC           0 :         appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
                               5480                 :                : 
  678 tgl@sss.pgh.pa.us        5481         [ +  + ]:CBC         113 :     if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
                               5482                 :             37 :         appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
                               5483                 :                : 
 3152 peter_e@gmx.net          5484                 :            113 :     appendPQExpBufferStr(query, ");\n");
                               5485                 :                : 
                               5486                 :                :     /*
                               5487                 :                :      * In binary-upgrade mode, we allow the replication to continue after the
                               5488                 :                :      * upgrade.
                               5489                 :                :      */
  613 akapila@postgresql.o     5490   [ +  +  +  - ]:            113 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5491                 :                :     {
                               5492         [ +  + ]:              5 :         if (subinfo->suboriginremotelsn)
                               5493                 :                :         {
                               5494                 :                :             /*
                               5495                 :                :              * Preserve the remote_lsn for the subscriber's replication
                               5496                 :                :              * origin. This value is required to start the replication from
                               5497                 :                :              * the position before the upgrade. This value will be stale if
                               5498                 :                :              * the publisher gets upgraded before the subscriber node.
                               5499                 :                :              * However, this shouldn't be a problem as the upgrade of the
                               5500                 :                :              * publisher ensures that all the transactions were replicated
                               5501                 :                :              * before upgrading it.
                               5502                 :                :              */
                               5503                 :              1 :             appendPQExpBufferStr(query,
                               5504                 :                :                                  "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
                               5505                 :              1 :             appendPQExpBufferStr(query,
                               5506                 :                :                                  "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
                               5507                 :              1 :             appendStringLiteralAH(query, subinfo->dobj.name, fout);
                               5508                 :              1 :             appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
                               5509                 :                :         }
                               5510                 :                : 
  277 michael@paquier.xyz      5511         [ +  + ]:              5 :         if (subinfo->subenabled)
                               5512                 :                :         {
                               5513                 :                :             /*
                               5514                 :                :              * Enable the subscription to allow the replication to continue
                               5515                 :                :              * after the upgrade.
                               5516                 :                :              */
  613 akapila@postgresql.o     5517                 :              1 :             appendPQExpBufferStr(query,
                               5518                 :                :                                  "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
                               5519                 :              1 :             appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
                               5520                 :                :         }
                               5521                 :                :     }
                               5522                 :                : 
 1370 tgl@sss.pgh.pa.us        5523         [ +  - ]:            113 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5524                 :            113 :         ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
                               5525                 :            113 :                      ARCHIVE_OPTS(.tag = subinfo->dobj.name,
                               5526                 :                :                                   .owner = subinfo->rolname,
                               5527                 :                :                                   .description = "SUBSCRIPTION",
                               5528                 :                :                                   .section = SECTION_POST_DATA,
                               5529                 :                :                                   .createStmt = query->data,
                               5530                 :                :                                   .dropStmt = delq->data));
                               5531                 :                : 
 3068 peter_e@gmx.net          5532         [ +  + ]:            113 :     if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us        5533                 :             37 :         dumpComment(fout, "SUBSCRIPTION", qsubname,
 3068 peter_e@gmx.net          5534                 :             37 :                     NULL, subinfo->rolname,
                               5535                 :             37 :                     subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5536                 :                : 
                               5537         [ -  + ]:            113 :     if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us        5538                 :UBC           0 :         dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
 3068 peter_e@gmx.net          5539                 :              0 :                      NULL, subinfo->rolname,
                               5540                 :              0 :                      subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5541                 :                : 
 3152 peter_e@gmx.net          5542                 :CBC         113 :     destroyPQExpBuffer(publications);
 1178 peter@eisentraut.org     5543                 :            113 :     free(pubnames);
                               5544                 :                : 
 3152 peter_e@gmx.net          5545                 :            113 :     destroyPQExpBuffer(delq);
                               5546                 :            113 :     destroyPQExpBuffer(query);
 2749 tgl@sss.pgh.pa.us        5547                 :            113 :     free(qsubname);
                               5548                 :                : }
                               5549                 :                : 
                               5550                 :                : /*
                               5551                 :                :  * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
                               5552                 :                :  * the object needs.
                               5553                 :                :  */
                               5554                 :                : static void
 2005 alvherre@alvh.no-ip.     5555                 :           5324 : append_depends_on_extension(Archive *fout,
                               5556                 :                :                             PQExpBuffer create,
                               5557                 :                :                             const DumpableObject *dobj,
                               5558                 :                :                             const char *catalog,
                               5559                 :                :                             const char *keyword,
                               5560                 :                :                             const char *objname)
                               5561                 :                : {
                               5562         [ +  + ]:           5324 :     if (dobj->depends_on_ext)
                               5563                 :                :     {
                               5564                 :                :         char       *nm;
                               5565                 :                :         PGresult   *res;
                               5566                 :                :         PQExpBuffer query;
                               5567                 :                :         int         ntups;
                               5568                 :                :         int         i_extname;
                               5569                 :                :         int         i;
                               5570                 :                : 
                               5571                 :                :         /* dodge fmtId() non-reentrancy */
                               5572                 :             42 :         nm = pg_strdup(objname);
                               5573                 :                : 
                               5574                 :             42 :         query = createPQExpBuffer();
                               5575                 :             42 :         appendPQExpBuffer(query,
                               5576                 :                :                           "SELECT e.extname "
                               5577                 :                :                           "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
                               5578                 :                :                           "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
                               5579                 :                :                           "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
                               5580                 :                :                           "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
                               5581                 :                :                           catalog,
                               5582                 :             42 :                           dobj->catId.oid);
                               5583                 :             42 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5584                 :             42 :         ntups = PQntuples(res);
                               5585                 :             42 :         i_extname = PQfnumber(res, "extname");
                               5586         [ +  + ]:             84 :         for (i = 0; i < ntups; i++)
                               5587                 :                :         {
  743                          5588                 :             42 :             appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
                               5589                 :                :                               keyword, nm,
 2005                          5590                 :             42 :                               fmtId(PQgetvalue(res, i, i_extname)));
                               5591                 :                :         }
                               5592                 :                : 
                               5593                 :             42 :         PQclear(res);
 2000                          5594                 :             42 :         destroyPQExpBuffer(query);
 2005                          5595                 :             42 :         pg_free(nm);
                               5596                 :                :     }
                               5597                 :           5324 : }
                               5598                 :                : 
                               5599                 :                : static Oid
 1721 akorotkov@postgresql     5600                 :UBC           0 : get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
                               5601                 :                : {
                               5602                 :                :     /*
                               5603                 :                :      * If the old version didn't assign an array type, but the new version
                               5604                 :                :      * does, we must select an unused type OID to assign.  This currently only
                               5605                 :                :      * happens for domains, when upgrading pre-v11 to v11 and up.
                               5606                 :                :      *
                               5607                 :                :      * Note: local state here is kind of ugly, but we must have some, since we
                               5608                 :                :      * mustn't choose the same unused OID more than once.
                               5609                 :                :      */
                               5610                 :                :     static Oid  next_possible_free_oid = FirstNormalObjectId;
                               5611                 :                :     PGresult   *res;
                               5612                 :                :     bool        is_dup;
                               5613                 :                : 
                               5614                 :                :     do
                               5615                 :                :     {
                               5616                 :              0 :         ++next_possible_free_oid;
                               5617                 :              0 :         printfPQExpBuffer(upgrade_query,
                               5618                 :                :                           "SELECT EXISTS(SELECT 1 "
                               5619                 :                :                           "FROM pg_catalog.pg_type "
                               5620                 :                :                           "WHERE oid = '%u'::pg_catalog.oid);",
                               5621                 :                :                           next_possible_free_oid);
                               5622                 :              0 :         res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5623                 :              0 :         is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
                               5624                 :              0 :         PQclear(res);
                               5625         [ #  # ]:              0 :     } while (is_dup);
                               5626                 :                : 
                               5627                 :              0 :     return next_possible_free_oid;
                               5628                 :                : }
                               5629                 :                : 
                               5630                 :                : static void
 4960 rhaas@postgresql.org     5631                 :CBC         943 : binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                               5632                 :                :                                          PQExpBuffer upgrade_buffer,
                               5633                 :                :                                          Oid pg_type_oid,
                               5634                 :                :                                          bool force_array_type,
                               5635                 :                :                                          bool include_multirange_type)
                               5636                 :                : {
 5735 bruce@momjian.us         5637                 :            943 :     PQExpBuffer upgrade_query = createPQExpBuffer();
                               5638                 :                :     PGresult   *res;
                               5639                 :                :     Oid         pg_type_array_oid;
                               5640                 :                :     Oid         pg_type_multirange_oid;
                               5641                 :                :     Oid         pg_type_multirange_array_oid;
                               5642                 :                :     TypeInfo   *tinfo;
                               5643                 :                : 
 4310 heikki.linnakangas@i     5644                 :            943 :     appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
 5735 bruce@momjian.us         5645                 :            943 :     appendPQExpBuffer(upgrade_buffer,
                               5646                 :                :                       "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5647                 :                :                       pg_type_oid);
                               5648                 :                : 
  369 dgustafsson@postgres     5649                 :            943 :     tinfo = findTypeByOid(pg_type_oid);
  366                          5650         [ +  - ]:            943 :     if (tinfo)
                               5651                 :            943 :         pg_type_array_oid = tinfo->typarray;
                               5652                 :                :     else
  366 dgustafsson@postgres     5653                 :UBC           0 :         pg_type_array_oid = InvalidOid;
                               5654                 :                : 
 2898 tgl@sss.pgh.pa.us        5655   [ +  +  -  + ]:CBC         943 :     if (!OidIsValid(pg_type_array_oid) && force_array_type)
 1721 akorotkov@postgresql     5656                 :UBC           0 :         pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5657                 :                : 
 5735 bruce@momjian.us         5658         [ +  + ]:CBC         943 :     if (OidIsValid(pg_type_array_oid))
                               5659                 :                :     {
 4310 heikki.linnakangas@i     5660                 :            941 :         appendPQExpBufferStr(upgrade_buffer,
                               5661                 :                :                              "\n-- For binary upgrade, must preserve pg_type array oid\n");
 5735 bruce@momjian.us         5662                 :            941 :         appendPQExpBuffer(upgrade_buffer,
                               5663                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5664                 :                :                           pg_type_array_oid);
                               5665                 :                :     }
                               5666                 :                : 
                               5667                 :                :     /*
                               5668                 :                :      * Pre-set the multirange type oid and its own array type oid.
                               5669                 :                :      */
 1721 akorotkov@postgresql     5670         [ +  + ]:            943 :     if (include_multirange_type)
                               5671                 :                :     {
                               5672         [ +  - ]:              8 :         if (fout->remoteVersion >= 140000)
                               5673                 :                :         {
 1322 tgl@sss.pgh.pa.us        5674                 :              8 :             printfPQExpBuffer(upgrade_query,
                               5675                 :                :                               "SELECT t.oid, t.typarray "
                               5676                 :                :                               "FROM pg_catalog.pg_type t "
                               5677                 :                :                               "JOIN pg_catalog.pg_range r "
                               5678                 :                :                               "ON t.oid = r.rngmultitypid "
                               5679                 :                :                               "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
                               5680                 :                :                               pg_type_oid);
                               5681                 :                : 
 1721 akorotkov@postgresql     5682                 :              8 :             res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5683                 :                : 
                               5684                 :              8 :             pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
                               5685                 :              8 :             pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
                               5686                 :                : 
                               5687                 :              8 :             PQclear(res);
                               5688                 :                :         }
                               5689                 :                :         else
                               5690                 :                :         {
 1721 akorotkov@postgresql     5691                 :UBC           0 :             pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5692                 :              0 :             pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5693                 :                :         }
                               5694                 :                : 
 1721 akorotkov@postgresql     5695                 :CBC           8 :         appendPQExpBufferStr(upgrade_buffer,
                               5696                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
                               5697                 :              8 :         appendPQExpBuffer(upgrade_buffer,
                               5698                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5699                 :                :                           pg_type_multirange_oid);
                               5700                 :              8 :         appendPQExpBufferStr(upgrade_buffer,
                               5701                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
                               5702                 :              8 :         appendPQExpBuffer(upgrade_buffer,
                               5703                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5704                 :                :                           pg_type_multirange_array_oid);
                               5705                 :                :     }
                               5706                 :                : 
 5735 bruce@momjian.us         5707                 :            943 :     destroyPQExpBuffer(upgrade_query);
                               5708                 :            943 : }
                               5709                 :                : 
                               5710                 :                : static void
 1370 tgl@sss.pgh.pa.us        5711                 :            868 : binary_upgrade_set_type_oids_by_rel(Archive *fout,
                               5712                 :                :                                     PQExpBuffer upgrade_buffer,
                               5713                 :                :                                     const TableInfo *tbinfo)
                               5714                 :                : {
                               5715                 :            868 :     Oid         pg_type_oid = tbinfo->reltype;
                               5716                 :                : 
 1887                          5717         [ +  - ]:            868 :     if (OidIsValid(pg_type_oid))
                               5718                 :            868 :         binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
                               5719                 :                :                                                  pg_type_oid, false, false);
 5735 bruce@momjian.us         5720                 :            868 : }
                               5721                 :                : 
                               5722                 :                : /*
                               5723                 :                :  * bsearch() comparator for BinaryUpgradeClassOidItem
                               5724                 :                :  */
                               5725                 :                : static int
  430 nathan@postgresql.or     5726                 :          12361 : BinaryUpgradeClassOidItemCmp(const void *p1, const void *p2)
                               5727                 :                : {
                               5728                 :          12361 :     BinaryUpgradeClassOidItem v1 = *((const BinaryUpgradeClassOidItem *) p1);
                               5729                 :          12361 :     BinaryUpgradeClassOidItem v2 = *((const BinaryUpgradeClassOidItem *) p2);
                               5730                 :                : 
                               5731                 :          12361 :     return pg_cmp_u32(v1.oid, v2.oid);
                               5732                 :                : }
                               5733                 :                : 
                               5734                 :                : /*
                               5735                 :                :  * collectBinaryUpgradeClassOids
                               5736                 :                :  *
                               5737                 :                :  * Construct a table of pg_class information required for
                               5738                 :                :  * binary_upgrade_set_pg_class_oids().  The table is sorted by OID for speed in
                               5739                 :                :  * lookup.
                               5740                 :                :  */
                               5741                 :                : static void
                               5742                 :             36 : collectBinaryUpgradeClassOids(Archive *fout)
                               5743                 :                : {
                               5744                 :                :     PGresult   *res;
                               5745                 :                :     const char *query;
                               5746                 :                : 
                               5747                 :             36 :     query = "SELECT c.oid, c.relkind, c.relfilenode, c.reltoastrelid, "
                               5748                 :                :         "ct.relfilenode, i.indexrelid, cti.relfilenode "
                               5749                 :                :         "FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_index i "
                               5750                 :                :         "ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
                               5751                 :                :         "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
                               5752                 :                :         "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
                               5753                 :                :         "ORDER BY c.oid;";
                               5754                 :                : 
                               5755                 :             36 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                               5756                 :                : 
                               5757                 :             36 :     nbinaryUpgradeClassOids = PQntuples(res);
                               5758                 :             36 :     binaryUpgradeClassOids = (BinaryUpgradeClassOidItem *)
                               5759                 :             36 :         pg_malloc(nbinaryUpgradeClassOids * sizeof(BinaryUpgradeClassOidItem));
                               5760                 :                : 
                               5761         [ +  + ]:          16826 :     for (int i = 0; i < nbinaryUpgradeClassOids; i++)
                               5762                 :                :     {
                               5763                 :          16790 :         binaryUpgradeClassOids[i].oid = atooid(PQgetvalue(res, i, 0));
                               5764                 :          16790 :         binaryUpgradeClassOids[i].relkind = *PQgetvalue(res, i, 1);
                               5765                 :          16790 :         binaryUpgradeClassOids[i].relfilenumber = atooid(PQgetvalue(res, i, 2));
                               5766                 :          16790 :         binaryUpgradeClassOids[i].toast_oid = atooid(PQgetvalue(res, i, 3));
                               5767                 :          16790 :         binaryUpgradeClassOids[i].toast_relfilenumber = atooid(PQgetvalue(res, i, 4));
                               5768                 :          16790 :         binaryUpgradeClassOids[i].toast_index_oid = atooid(PQgetvalue(res, i, 5));
                               5769                 :          16790 :         binaryUpgradeClassOids[i].toast_index_relfilenumber = atooid(PQgetvalue(res, i, 6));
                               5770                 :                :     }
                               5771                 :                : 
                               5772                 :             36 :     PQclear(res);
                               5773                 :             36 : }
                               5774                 :                : 
                               5775                 :                : static void
 4960 rhaas@postgresql.org     5776                 :           1254 : binary_upgrade_set_pg_class_oids(Archive *fout,
                               5777                 :                :                                  PQExpBuffer upgrade_buffer, Oid pg_class_oid)
                               5778                 :                : {
  430 nathan@postgresql.or     5779                 :           1254 :     BinaryUpgradeClassOidItem key = {0};
                               5780                 :                :     BinaryUpgradeClassOidItem *entry;
                               5781                 :                : 
                               5782         [ -  + ]:           1254 :     Assert(binaryUpgradeClassOids);
                               5783                 :                : 
                               5784                 :                :     /*
                               5785                 :                :      * Preserve the OID and relfilenumber of the table, table's index, table's
                               5786                 :                :      * toast table and toast table's index if any.
                               5787                 :                :      *
                               5788                 :                :      * One complexity is that the current table definition might not require
                               5789                 :                :      * the creation of a TOAST table, but the old database might have a TOAST
                               5790                 :                :      * table that was created earlier, before some wide columns were dropped.
                               5791                 :                :      * By setting the TOAST oid we force creation of the TOAST heap and index
                               5792                 :                :      * by the new backend, so we can copy the files during binary upgrade
                               5793                 :                :      * without worrying about this case.
                               5794                 :                :      */
                               5795                 :           1254 :     key.oid = pg_class_oid;
                               5796                 :           1254 :     entry = bsearch(&key, binaryUpgradeClassOids, nbinaryUpgradeClassOids,
                               5797                 :                :                     sizeof(BinaryUpgradeClassOidItem),
                               5798                 :                :                     BinaryUpgradeClassOidItemCmp);
                               5799                 :                : 
 4310 heikki.linnakangas@i     5800                 :           1254 :     appendPQExpBufferStr(upgrade_buffer,
                               5801                 :                :                          "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
                               5802                 :                : 
  430 nathan@postgresql.or     5803         [ +  + ]:           1254 :     if (entry->relkind != RELKIND_INDEX &&
                               5804         [ +  + ]:            977 :         entry->relkind != RELKIND_PARTITIONED_INDEX)
                               5805                 :                :     {
 5722 bruce@momjian.us         5806                 :            952 :         appendPQExpBuffer(upgrade_buffer,
                               5807                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5808                 :                :                           pg_class_oid);
                               5809                 :                : 
                               5810                 :                :         /*
                               5811                 :                :          * Not every relation has storage. Also, in a pre-v12 database,
                               5812                 :                :          * partitioned tables have a relfilenumber, which should not be
                               5813                 :                :          * preserved when upgrading.
                               5814                 :                :          */
  430 nathan@postgresql.or     5815         [ +  + ]:            952 :         if (RelFileNumberIsValid(entry->relfilenumber) &&
                               5816         [ +  - ]:            790 :             entry->relkind != RELKIND_PARTITIONED_TABLE)
 1328 rhaas@postgresql.org     5817                 :            790 :             appendPQExpBuffer(upgrade_buffer,
                               5818                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               5819                 :                :                               entry->relfilenumber);
                               5820                 :                : 
                               5821                 :                :         /*
                               5822                 :                :          * In a pre-v12 database, partitioned tables might be marked as having
                               5823                 :                :          * toast tables, but we should ignore them if so.
                               5824                 :                :          */
  430 nathan@postgresql.or     5825         [ +  + ]:            952 :         if (OidIsValid(entry->toast_oid) &&
                               5826         [ +  - ]:            280 :             entry->relkind != RELKIND_PARTITIONED_TABLE)
                               5827                 :                :         {
 5358 bruce@momjian.us         5828                 :            280 :             appendPQExpBuffer(upgrade_buffer,
                               5829                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5830                 :                :                               entry->toast_oid);
 1328 rhaas@postgresql.org     5831                 :            280 :             appendPQExpBuffer(upgrade_buffer,
                               5832                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
                               5833                 :                :                               entry->toast_relfilenumber);
                               5834                 :                : 
                               5835                 :                :             /* every toast table has an index */
 5358 bruce@momjian.us         5836                 :            280 :             appendPQExpBuffer(upgrade_buffer,
                               5837                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5838                 :                :                               entry->toast_index_oid);
 1328 rhaas@postgresql.org     5839                 :            280 :             appendPQExpBuffer(upgrade_buffer,
                               5840                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5841                 :                :                               entry->toast_index_relfilenumber);
                               5842                 :                :         }
                               5843                 :                :     }
                               5844                 :                :     else
                               5845                 :                :     {
                               5846                 :                :         /* Preserve the OID and relfilenumber of the index */
 5722 bruce@momjian.us         5847                 :            302 :         appendPQExpBuffer(upgrade_buffer,
                               5848                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5849                 :                :                           pg_class_oid);
 1328 rhaas@postgresql.org     5850                 :            302 :         appendPQExpBuffer(upgrade_buffer,
                               5851                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5852                 :                :                           entry->relfilenumber);
                               5853                 :                :     }
                               5854                 :                : 
 4310 heikki.linnakangas@i     5855                 :           1254 :     appendPQExpBufferChar(upgrade_buffer, '\n');
 5735 bruce@momjian.us         5856                 :           1254 : }
                               5857                 :                : 
                               5858                 :                : /*
                               5859                 :                :  * If the DumpableObject is a member of an extension, add a suitable
                               5860                 :                :  * ALTER EXTENSION ADD command to the creation commands in upgrade_buffer.
                               5861                 :                :  *
                               5862                 :                :  * For somewhat historical reasons, objname should already be quoted,
                               5863                 :                :  * but not objnamespace (if any).
                               5864                 :                :  */
                               5865                 :                : static void
 5323 tgl@sss.pgh.pa.us        5866                 :           1499 : binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                               5867                 :                :                                 const DumpableObject *dobj,
                               5868                 :                :                                 const char *objtype,
                               5869                 :                :                                 const char *objname,
                               5870                 :                :                                 const char *objnamespace)
                               5871                 :                : {
                               5872                 :           1499 :     DumpableObject *extobj = NULL;
                               5873                 :                :     int         i;
                               5874                 :                : 
                               5875         [ +  + ]:           1499 :     if (!dobj->ext_member)
                               5876                 :           1483 :         return;
                               5877                 :                : 
                               5878                 :                :     /*
                               5879                 :                :      * Find the parent extension.  We could avoid this search if we wanted to
                               5880                 :                :      * add a link field to DumpableObject, but the space costs of that would
                               5881                 :                :      * be considerable.  We assume that member objects could only have a
                               5882                 :                :      * direct dependency on their own extension, not any others.
                               5883                 :                :      */
                               5884         [ +  - ]:             16 :     for (i = 0; i < dobj->nDeps; i++)
                               5885                 :                :     {
                               5886                 :             16 :         extobj = findObjectByDumpId(dobj->dependencies[i]);
                               5887   [ +  -  +  - ]:             16 :         if (extobj && extobj->objType == DO_EXTENSION)
                               5888                 :             16 :             break;
 5323 tgl@sss.pgh.pa.us        5889                 :UBC           0 :         extobj = NULL;
                               5890                 :                :     }
 5323 tgl@sss.pgh.pa.us        5891         [ -  + ]:CBC          16 :     if (extobj == NULL)
 1247 tgl@sss.pgh.pa.us        5892                 :UBC           0 :         pg_fatal("could not find parent extension for %s %s",
                               5893                 :                :                  objtype, objname);
                               5894                 :                : 
 4310 heikki.linnakangas@i     5895                 :CBC          16 :     appendPQExpBufferStr(upgrade_buffer,
                               5896                 :                :                          "\n-- For binary upgrade, handle extension membership the hard way\n");
 2749 tgl@sss.pgh.pa.us        5897                 :             16 :     appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
 5323                          5898                 :             16 :                       fmtId(extobj->name),
                               5899                 :                :                       objtype);
 2749                          5900   [ +  +  +  - ]:             16 :     if (objnamespace && *objnamespace)
                               5901                 :             13 :         appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
                               5902                 :             16 :     appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
                               5903                 :                : }
                               5904                 :                : 
                               5905                 :                : /*
                               5906                 :                :  * getNamespaces:
                               5907                 :                :  *    get information about all namespaces in the system catalogs
                               5908                 :                :  */
                               5909                 :                : void
  431 nathan@postgresql.or     5910                 :            186 : getNamespaces(Archive *fout)
                               5911                 :                : {
                               5912                 :                :     PGresult   *res;
                               5913                 :                :     int         ntups;
                               5914                 :                :     int         i;
                               5915                 :                :     PQExpBuffer query;
                               5916                 :                :     NamespaceInfo *nsinfo;
                               5917                 :                :     int         i_tableoid;
                               5918                 :                :     int         i_oid;
                               5919                 :                :     int         i_nspname;
                               5920                 :                :     int         i_nspowner;
                               5921                 :                :     int         i_nspacl;
                               5922                 :                :     int         i_acldefault;
                               5923                 :                : 
 8520 tgl@sss.pgh.pa.us        5924                 :            186 :     query = createPQExpBuffer();
                               5925                 :                : 
                               5926                 :                :     /*
                               5927                 :                :      * we fetch all namespaces including system ones, so that every object we
                               5928                 :                :      * read in can be linked to a containing namespace.
                               5929                 :                :      */
 1096 drowley@postgresql.o     5930                 :            186 :     appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
                               5931                 :                :                          "n.nspowner, "
                               5932                 :                :                          "n.nspacl, "
                               5933                 :                :                          "acldefault('n', n.nspowner) AS acldefault "
                               5934                 :                :                          "FROM pg_namespace n");
                               5935                 :                : 
 4960 rhaas@postgresql.org     5936                 :            186 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5937                 :                : 
10226 bruce@momjian.us         5938                 :            186 :     ntups = PQntuples(res);
                               5939                 :                : 
 5034                          5940                 :            186 :     nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
                               5941                 :                : 
 7945 tgl@sss.pgh.pa.us        5942                 :            186 :     i_tableoid = PQfnumber(res, "tableoid");
10226 bruce@momjian.us         5943                 :            186 :     i_oid = PQfnumber(res, "oid");
 8520 tgl@sss.pgh.pa.us        5944                 :            186 :     i_nspname = PQfnumber(res, "nspname");
 1531 noah@leadboat.com        5945                 :            186 :     i_nspowner = PQfnumber(res, "nspowner");
 8520 tgl@sss.pgh.pa.us        5946                 :            186 :     i_nspacl = PQfnumber(res, "nspacl");
 1370                          5947                 :            186 :     i_acldefault = PQfnumber(res, "acldefault");
                               5948                 :                : 
10226 bruce@momjian.us         5949         [ +  + ]:           1620 :     for (i = 0; i < ntups; i++)
                               5950                 :                :     {
                               5951                 :                :         const char *nspowner;
                               5952                 :                : 
 7945 tgl@sss.pgh.pa.us        5953                 :           1434 :         nsinfo[i].dobj.objType = DO_NAMESPACE;
                               5954                 :           1434 :         nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               5955                 :           1434 :         nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5956                 :           1434 :         AssignDumpId(&nsinfo[i].dobj);
 5034 bruce@momjian.us         5957                 :           1434 :         nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
 1370 tgl@sss.pgh.pa.us        5958                 :           1434 :         nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
                               5959                 :           1434 :         nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               5960                 :           1434 :         nsinfo[i].dacl.privtype = 0;
                               5961                 :           1434 :         nsinfo[i].dacl.initprivs = NULL;
 1345                          5962                 :           1434 :         nspowner = PQgetvalue(res, i, i_nspowner);
                               5963                 :           1434 :         nsinfo[i].nspowner = atooid(nspowner);
                               5964                 :           1434 :         nsinfo[i].rolname = getRoleName(nspowner);
                               5965                 :                : 
                               5966                 :                :         /* Decide whether to dump this namespace */
 3440 sfrost@snowman.net       5967                 :           1434 :         selectDumpableNamespace(&nsinfo[i], fout);
                               5968                 :                : 
                               5969                 :                :         /* Mark whether namespace has an ACL */
 1370 tgl@sss.pgh.pa.us        5970         [ +  + ]:           1434 :         if (!PQgetisnull(res, i, i_nspacl))
                               5971                 :            626 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               5972                 :                : 
                               5973                 :                :         /*
                               5974                 :                :          * We ignore any pg_init_privs.initprivs entry for the public schema
                               5975                 :                :          * and assume a predetermined default, for several reasons.  First,
                               5976                 :                :          * dropping and recreating the schema removes its pg_init_privs entry,
                               5977                 :                :          * but an empty destination database starts with this ACL nonetheless.
                               5978                 :                :          * Second, we support dump/reload of public schema ownership changes.
                               5979                 :                :          * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
                               5980                 :                :          * initprivs continues to reflect the initial owner.  Hence,
                               5981                 :                :          * synthesize the value that nspacl will have after the restore's
                               5982                 :                :          * ALTER SCHEMA OWNER.  Third, this makes the destination database
                               5983                 :                :          * match the source's ACL, even if the latter was an initdb-default
                               5984                 :                :          * ACL, which changed in v15.  An upgrade pulls in changes to most
                               5985                 :                :          * system object ACLs that the DBA had not customized.  We've made the
                               5986                 :                :          * public schema depart from that, because changing its ACL so easily
                               5987                 :                :          * breaks applications.
                               5988                 :                :          */
                               5989         [ +  + ]:           1434 :         if (strcmp(nsinfo[i].dobj.name, "public") == 0)
                               5990                 :                :         {
                               5991                 :            182 :             PQExpBuffer aclarray = createPQExpBuffer();
                               5992                 :            182 :             PQExpBuffer aclitem = createPQExpBuffer();
                               5993                 :                : 
                               5994                 :                :             /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
                               5995                 :            182 :             appendPQExpBufferChar(aclarray, '{');
                               5996                 :            182 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               5997                 :            182 :             appendPQExpBufferStr(aclitem, "=UC/");
                               5998                 :            182 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               5999                 :            182 :             appendPGArray(aclarray, aclitem->data);
                               6000                 :            182 :             resetPQExpBuffer(aclitem);
                               6001                 :            182 :             appendPQExpBufferStr(aclitem, "=U/");
                               6002                 :            182 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               6003                 :            182 :             appendPGArray(aclarray, aclitem->data);
                               6004                 :            182 :             appendPQExpBufferChar(aclarray, '}');
                               6005                 :                : 
                               6006                 :            182 :             nsinfo[i].dacl.privtype = 'i';
                               6007                 :            182 :             nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
                               6008                 :            182 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6009                 :                : 
                               6010                 :            182 :             destroyPQExpBuffer(aclarray);
                               6011                 :            182 :             destroyPQExpBuffer(aclitem);
                               6012                 :                :         }
                               6013                 :                :     }
                               6014                 :                : 
10226 bruce@momjian.us         6015                 :            186 :     PQclear(res);
 8800 tgl@sss.pgh.pa.us        6016                 :            186 :     destroyPQExpBuffer(query);
10323 scrappy@hub.org          6017                 :            186 : }
                               6018                 :                : 
                               6019                 :                : /*
                               6020                 :                :  * findNamespace:
                               6021                 :                :  *      given a namespace OID, look up the info read by getNamespaces
                               6022                 :                :  */
                               6023                 :                : static NamespaceInfo *
 1838 peter@eisentraut.org     6024                 :         714800 : findNamespace(Oid nsoid)
                               6025                 :                : {
                               6026                 :                :     NamespaceInfo *nsinfo;
                               6027                 :                : 
 3251 tgl@sss.pgh.pa.us        6028                 :         714800 :     nsinfo = findNamespaceByOid(nsoid);
 4852                          6029         [ -  + ]:         714800 :     if (nsinfo == NULL)
 1247 tgl@sss.pgh.pa.us        6030                 :UBC           0 :         pg_fatal("schema with OID %u does not exist", nsoid);
 4852 tgl@sss.pgh.pa.us        6031                 :CBC      714800 :     return nsinfo;
                               6032                 :                : }
                               6033                 :                : 
                               6034                 :                : /*
                               6035                 :                :  * getExtensions:
                               6036                 :                :  *    read all extensions in the system catalogs and return them in the
                               6037                 :                :  * ExtensionInfo* structure
                               6038                 :                :  *
                               6039                 :                :  *  numExtensions is set to the number of extensions read in
                               6040                 :                :  */
                               6041                 :                : ExtensionInfo *
 3524                          6042                 :            186 : getExtensions(Archive *fout, int *numExtensions)
                               6043                 :                : {
                               6044                 :            186 :     DumpOptions *dopt = fout->dopt;
                               6045                 :                :     PGresult   *res;
                               6046                 :                :     int         ntups;
                               6047                 :                :     int         i;
                               6048                 :                :     PQExpBuffer query;
  339 dgustafsson@postgres     6049                 :            186 :     ExtensionInfo *extinfo = NULL;
                               6050                 :                :     int         i_tableoid;
                               6051                 :                :     int         i_oid;
                               6052                 :                :     int         i_extname;
                               6053                 :                :     int         i_nspname;
                               6054                 :                :     int         i_extrelocatable;
                               6055                 :                :     int         i_extversion;
                               6056                 :                :     int         i_extconfig;
                               6057                 :                :     int         i_extcondition;
                               6058                 :                : 
 5324 tgl@sss.pgh.pa.us        6059                 :            186 :     query = createPQExpBuffer();
                               6060                 :                : 
 4310 heikki.linnakangas@i     6061                 :            186 :     appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
                               6062                 :                :                          "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
                               6063                 :                :                          "FROM pg_extension x "
                               6064                 :                :                          "JOIN pg_namespace n ON n.oid = x.extnamespace");
                               6065                 :                : 
 4960 rhaas@postgresql.org     6066                 :            186 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6067                 :                : 
 5324 tgl@sss.pgh.pa.us        6068                 :            186 :     ntups = PQntuples(res);
  339 dgustafsson@postgres     6069         [ -  + ]:            186 :     if (ntups == 0)
  339 dgustafsson@postgres     6070                 :UBC           0 :         goto cleanup;
                               6071                 :                : 
 5034 bruce@momjian.us         6072                 :CBC         186 :     extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
                               6073                 :                : 
 5324 tgl@sss.pgh.pa.us        6074                 :            186 :     i_tableoid = PQfnumber(res, "tableoid");
                               6075                 :            186 :     i_oid = PQfnumber(res, "oid");
                               6076                 :            186 :     i_extname = PQfnumber(res, "extname");
                               6077                 :            186 :     i_nspname = PQfnumber(res, "nspname");
 5323                          6078                 :            186 :     i_extrelocatable = PQfnumber(res, "extrelocatable");
                               6079                 :            186 :     i_extversion = PQfnumber(res, "extversion");
 5324                          6080                 :            186 :     i_extconfig = PQfnumber(res, "extconfig");
                               6081                 :            186 :     i_extcondition = PQfnumber(res, "extcondition");
                               6082                 :                : 
                               6083         [ +  + ]:            397 :     for (i = 0; i < ntups; i++)
                               6084                 :                :     {
                               6085                 :            211 :         extinfo[i].dobj.objType = DO_EXTENSION;
                               6086                 :            211 :         extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6087                 :            211 :         extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6088                 :            211 :         AssignDumpId(&extinfo[i].dobj);
 5034 bruce@momjian.us         6089                 :            211 :         extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
                               6090                 :            211 :         extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
 5323 tgl@sss.pgh.pa.us        6091                 :            211 :         extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
 5034 bruce@momjian.us         6092                 :            211 :         extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
                               6093                 :            211 :         extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
                               6094                 :            211 :         extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
                               6095                 :                : 
                               6096                 :                :         /* Decide whether we want to dump it */
 3524 tgl@sss.pgh.pa.us        6097                 :            211 :         selectDumpableExtension(&(extinfo[i]), dopt);
                               6098                 :                :     }
                               6099                 :                : 
  339 dgustafsson@postgres     6100                 :            186 : cleanup:
 5324 tgl@sss.pgh.pa.us        6101                 :            186 :     PQclear(res);
                               6102                 :            186 :     destroyPQExpBuffer(query);
                               6103                 :                : 
                               6104                 :            186 :     *numExtensions = ntups;
                               6105                 :                : 
                               6106                 :            186 :     return extinfo;
                               6107                 :                : }
                               6108                 :                : 
                               6109                 :                : /*
                               6110                 :                :  * getTypes:
                               6111                 :                :  *    get information about all types in the system catalogs
                               6112                 :                :  *
                               6113                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               6114                 :                :  * findFuncByOid().
                               6115                 :                :  */
                               6116                 :                : void
  431 nathan@postgresql.or     6117                 :            185 : getTypes(Archive *fout)
                               6118                 :                : {
                               6119                 :                :     PGresult   *res;
                               6120                 :                :     int         ntups;
                               6121                 :                :     int         i;
 9278 bruce@momjian.us         6122                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               6123                 :                :     TypeInfo   *tyinfo;
                               6124                 :                :     ShellTypeInfo *stinfo;
                               6125                 :                :     int         i_tableoid;
                               6126                 :                :     int         i_oid;
                               6127                 :                :     int         i_typname;
                               6128                 :                :     int         i_typnamespace;
                               6129                 :                :     int         i_typacl;
                               6130                 :                :     int         i_acldefault;
                               6131                 :                :     int         i_typowner;
                               6132                 :                :     int         i_typelem;
                               6133                 :                :     int         i_typrelid;
                               6134                 :                :     int         i_typrelkind;
                               6135                 :                :     int         i_typtype;
                               6136                 :                :     int         i_typisdefined;
                               6137                 :                :     int         i_isarray;
                               6138                 :                :     int         i_typarray;
                               6139                 :                : 
                               6140                 :                :     /*
                               6141                 :                :      * we include even the built-in types because those may be used as array
                               6142                 :                :      * elements by user-defined types
                               6143                 :                :      *
                               6144                 :                :      * we filter out the built-in types when we dump out the types
                               6145                 :                :      *
                               6146                 :                :      * same approach for undefined (shell) types and array types
                               6147                 :                :      *
                               6148                 :                :      * Note: as of 8.3 we can reliably detect whether a type is an
                               6149                 :                :      * auto-generated array type by checking the element type's typarray.
                               6150                 :                :      * (Before that the test is capable of generating false positives.) We
                               6151                 :                :      * still check for name beginning with '_', though, so as to avoid the
                               6152                 :                :      * cost of the subselect probe for all standard types.  This would have to
                               6153                 :                :      * be revisited if the backend ever allows renaming of array types.
                               6154                 :                :      */
 1096 drowley@postgresql.o     6155                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
                               6156                 :                :                          "typnamespace, typacl, "
                               6157                 :                :                          "acldefault('T', typowner) AS acldefault, "
                               6158                 :                :                          "typowner, "
                               6159                 :                :                          "typelem, typrelid, typarray, "
                               6160                 :                :                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                               6161                 :                :                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
                               6162                 :                :                          "typtype, typisdefined, "
                               6163                 :                :                          "typname[0] = '_' AND typelem != 0 AND "
                               6164                 :                :                          "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
                               6165                 :                :                          "FROM pg_type");
                               6166                 :                : 
 4960 rhaas@postgresql.org     6167                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6168                 :                : 
10226 bruce@momjian.us         6169                 :            185 :     ntups = PQntuples(res);
                               6170                 :                : 
 5034                          6171                 :            185 :     tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
                               6172                 :                : 
 7945 tgl@sss.pgh.pa.us        6173                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
10226 bruce@momjian.us         6174                 :            185 :     i_oid = PQfnumber(res, "oid");
 8520 tgl@sss.pgh.pa.us        6175                 :            185 :     i_typname = PQfnumber(res, "typname");
                               6176                 :            185 :     i_typnamespace = PQfnumber(res, "typnamespace");
 4654                          6177                 :            185 :     i_typacl = PQfnumber(res, "typacl");
 1370                          6178                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
 1345                          6179                 :            185 :     i_typowner = PQfnumber(res, "typowner");
 8520                          6180                 :            185 :     i_typelem = PQfnumber(res, "typelem");
                               6181                 :            185 :     i_typrelid = PQfnumber(res, "typrelid");
 8423 bruce@momjian.us         6182                 :            185 :     i_typrelkind = PQfnumber(res, "typrelkind");
 8520 tgl@sss.pgh.pa.us        6183                 :            185 :     i_typtype = PQfnumber(res, "typtype");
                               6184                 :            185 :     i_typisdefined = PQfnumber(res, "typisdefined");
 6693                          6185                 :            185 :     i_isarray = PQfnumber(res, "isarray");
  369 dgustafsson@postgres     6186                 :            185 :     i_typarray = PQfnumber(res, "typarray");
                               6187                 :                : 
10226 bruce@momjian.us         6188         [ +  + ]:         134940 :     for (i = 0; i < ntups; i++)
                               6189                 :                :     {
 5736                          6190                 :         134755 :         tyinfo[i].dobj.objType = DO_TYPE;
                               6191                 :         134755 :         tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6192                 :         134755 :         tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6193                 :         134755 :         AssignDumpId(&tyinfo[i].dobj);
 5034                          6194                 :         134755 :         tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
 4961 rhaas@postgresql.org     6195                 :         269510 :         tyinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6196                 :         134755 :             findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
 1370 tgl@sss.pgh.pa.us        6197                 :         134755 :         tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
                               6198                 :         134755 :         tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6199                 :         134755 :         tyinfo[i].dacl.privtype = 0;
                               6200                 :         134755 :         tyinfo[i].dacl.initprivs = NULL;
 1467                          6201                 :         134755 :         tyinfo[i].ftypname = NULL;  /* may get filled later */
 1345                          6202                 :         134755 :         tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
 5736 bruce@momjian.us         6203                 :         134755 :         tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
                               6204                 :         134755 :         tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
                               6205                 :         134755 :         tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
                               6206                 :         134755 :         tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
                               6207                 :         134755 :         tyinfo[i].shellType = NULL;
                               6208                 :                : 
 8520 tgl@sss.pgh.pa.us        6209         [ +  + ]:         134755 :         if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
 5736 bruce@momjian.us         6210                 :         134697 :             tyinfo[i].isDefined = true;
                               6211                 :                :         else
                               6212                 :             58 :             tyinfo[i].isDefined = false;
                               6213                 :                : 
 6693 tgl@sss.pgh.pa.us        6214         [ +  + ]:         134755 :         if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
 5736 bruce@momjian.us         6215                 :          64666 :             tyinfo[i].isArray = true;
                               6216                 :                :         else
                               6217                 :          70089 :             tyinfo[i].isArray = false;
                               6218                 :                : 
  369 dgustafsson@postgres     6219                 :         134755 :         tyinfo[i].typarray = atooid(PQgetvalue(res, i, i_typarray));
                               6220                 :                : 
  570 tgl@sss.pgh.pa.us        6221         [ +  + ]:         134755 :         if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
 1721 akorotkov@postgresql     6222                 :           1254 :             tyinfo[i].isMultirange = true;
                               6223                 :                :         else
                               6224                 :         133501 :             tyinfo[i].isMultirange = false;
                               6225                 :                : 
                               6226                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6227                 :         134755 :         selectDumpableType(&tyinfo[i], fout);
                               6228                 :                : 
                               6229                 :                :         /* Mark whether type has an ACL */
 1370 tgl@sss.pgh.pa.us        6230         [ +  + ]:         134755 :         if (!PQgetisnull(res, i, i_typacl))
                               6231                 :            229 :             tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6232                 :                : 
                               6233                 :                :         /*
                               6234                 :                :          * If it's a domain, fetch info about its constraints, if any
                               6235                 :                :          */
 5736 bruce@momjian.us         6236                 :         134755 :         tyinfo[i].nDomChecks = 0;
                               6237                 :         134755 :         tyinfo[i].domChecks = NULL;
   47 alvherre@kurilemu.de     6238                 :         134755 :         tyinfo[i].notnull = NULL;
 3440 sfrost@snowman.net       6239         [ +  + ]:         134755 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               6240         [ +  + ]:          15879 :             tyinfo[i].typtype == TYPTYPE_DOMAIN)
 4961 rhaas@postgresql.org     6241                 :            164 :             getDomainConstraints(fout, &(tyinfo[i]));
                               6242                 :                : 
                               6243                 :                :         /*
                               6244                 :                :          * If it's a base type, make a DumpableObject representing a shell
                               6245                 :                :          * definition of the type.  We will need to dump that ahead of the I/O
                               6246                 :                :          * functions for the type.  Similarly, range types need a shell
                               6247                 :                :          * definition in case they have a canonicalize function.
                               6248                 :                :          *
                               6249                 :                :          * Note: the shell type doesn't have a catId.  You might think it
                               6250                 :                :          * should copy the base type's catId, but then it might capture the
                               6251                 :                :          * pg_depend entries for the type, which we don't want.
                               6252                 :                :          */
 3440 sfrost@snowman.net       6253         [ +  + ]:         134755 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               6254         [ +  + ]:          15879 :             (tyinfo[i].typtype == TYPTYPE_BASE ||
                               6255         [ +  + ]:           7723 :              tyinfo[i].typtype == TYPTYPE_RANGE))
                               6256                 :                :         {
 5034 bruce@momjian.us         6257                 :           8292 :             stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
 7128 tgl@sss.pgh.pa.us        6258                 :           8292 :             stinfo->dobj.objType = DO_SHELL_TYPE;
                               6259                 :           8292 :             stinfo->dobj.catId = nilCatalogId;
                               6260                 :           8292 :             AssignDumpId(&stinfo->dobj);
 5034 bruce@momjian.us         6261                 :           8292 :             stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
 5736                          6262                 :           8292 :             stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
                               6263                 :           8292 :             stinfo->baseType = &(tyinfo[i]);
                               6264                 :           8292 :             tyinfo[i].shellType = stinfo;
                               6265                 :                : 
                               6266                 :                :             /*
                               6267                 :                :              * Initially mark the shell type as not to be dumped.  We'll only
                               6268                 :                :              * dump it if the I/O or canonicalize functions need to be dumped;
                               6269                 :                :              * this is taken care of while sorting dependencies.
                               6270                 :                :              */
 3440 sfrost@snowman.net       6271                 :           8292 :             stinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               6272                 :                :         }
                               6273                 :                :     }
                               6274                 :                : 
10226 bruce@momjian.us         6275                 :            185 :     PQclear(res);
                               6276                 :                : 
 8800 tgl@sss.pgh.pa.us        6277                 :            185 :     destroyPQExpBuffer(query);
10651 scrappy@hub.org          6278                 :            185 : }
                               6279                 :                : 
                               6280                 :                : /*
                               6281                 :                :  * getOperators:
                               6282                 :                :  *    get information about all operators in the system catalogs
                               6283                 :                :  */
                               6284                 :                : void
  431 nathan@postgresql.or     6285                 :            185 : getOperators(Archive *fout)
                               6286                 :                : {
                               6287                 :                :     PGresult   *res;
                               6288                 :                :     int         ntups;
                               6289                 :                :     int         i;
 9278 bruce@momjian.us         6290                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               6291                 :                :     OprInfo    *oprinfo;
                               6292                 :                :     int         i_tableoid;
                               6293                 :                :     int         i_oid;
                               6294                 :                :     int         i_oprname;
                               6295                 :                :     int         i_oprnamespace;
                               6296                 :                :     int         i_oprowner;
                               6297                 :                :     int         i_oprkind;
                               6298                 :                :     int         i_oprleft;
                               6299                 :                :     int         i_oprright;
                               6300                 :                :     int         i_oprcode;
                               6301                 :                : 
                               6302                 :                :     /*
                               6303                 :                :      * find all operators, including builtin operators; we filter out
                               6304                 :                :      * system-defined operators at dump-out time.
                               6305                 :                :      */
                               6306                 :                : 
 1096 drowley@postgresql.o     6307                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
                               6308                 :                :                          "oprnamespace, "
                               6309                 :                :                          "oprowner, "
                               6310                 :                :                          "oprkind, "
                               6311                 :                :                          "oprleft, "
                               6312                 :                :                          "oprright, "
                               6313                 :                :                          "oprcode::oid AS oprcode "
                               6314                 :                :                          "FROM pg_operator");
                               6315                 :                : 
 4960 rhaas@postgresql.org     6316                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6317                 :                : 
10226 bruce@momjian.us         6318                 :            185 :     ntups = PQntuples(res);
                               6319                 :                : 
 5034                          6320                 :            185 :     oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
                               6321                 :                : 
 7945 tgl@sss.pgh.pa.us        6322                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
10226 bruce@momjian.us         6323                 :            185 :     i_oid = PQfnumber(res, "oid");
 8520 tgl@sss.pgh.pa.us        6324                 :            185 :     i_oprname = PQfnumber(res, "oprname");
                               6325                 :            185 :     i_oprnamespace = PQfnumber(res, "oprnamespace");
 1345                          6326                 :            185 :     i_oprowner = PQfnumber(res, "oprowner");
 4993 peter_e@gmx.net          6327                 :            185 :     i_oprkind = PQfnumber(res, "oprkind");
   37 noah@leadboat.com        6328                 :            185 :     i_oprleft = PQfnumber(res, "oprleft");
                               6329                 :            185 :     i_oprright = PQfnumber(res, "oprright");
 8520 tgl@sss.pgh.pa.us        6330                 :            185 :     i_oprcode = PQfnumber(res, "oprcode");
                               6331                 :                : 
10226 bruce@momjian.us         6332         [ +  + ]:         148148 :     for (i = 0; i < ntups; i++)
                               6333                 :                :     {
 7945 tgl@sss.pgh.pa.us        6334                 :         147963 :         oprinfo[i].dobj.objType = DO_OPERATOR;
                               6335                 :         147963 :         oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6336                 :         147963 :         oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6337                 :         147963 :         AssignDumpId(&oprinfo[i].dobj);
 5034 bruce@momjian.us         6338                 :         147963 :         oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
 4961 rhaas@postgresql.org     6339                 :         295926 :         oprinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6340                 :         147963 :             findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
 1345 tgl@sss.pgh.pa.us        6341                 :         147963 :         oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
 4993 peter_e@gmx.net          6342                 :         147963 :         oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
   37 noah@leadboat.com        6343                 :         147963 :         oprinfo[i].oprleft = atooid(PQgetvalue(res, i, i_oprleft));
                               6344                 :         147963 :         oprinfo[i].oprright = atooid(PQgetvalue(res, i, i_oprright));
 7945 tgl@sss.pgh.pa.us        6345                 :         147963 :         oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
                               6346                 :                : 
                               6347                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6348                 :         147963 :         selectDumpableObject(&(oprinfo[i].dobj), fout);
                               6349                 :                :     }
                               6350                 :                : 
10226 bruce@momjian.us         6351                 :            185 :     PQclear(res);
                               6352                 :                : 
 8800 tgl@sss.pgh.pa.us        6353                 :            185 :     destroyPQExpBuffer(query);
10651 scrappy@hub.org          6354                 :            185 : }
                               6355                 :                : 
                               6356                 :                : /*
                               6357                 :                :  * getCollations:
                               6358                 :                :  *    get information about all collations in the system catalogs
                               6359                 :                :  */
                               6360                 :                : void
  431 nathan@postgresql.or     6361                 :            185 : getCollations(Archive *fout)
                               6362                 :                : {
                               6363                 :                :     PGresult   *res;
                               6364                 :                :     int         ntups;
                               6365                 :                :     int         i;
                               6366                 :                :     PQExpBuffer query;
                               6367                 :                :     CollInfo   *collinfo;
                               6368                 :                :     int         i_tableoid;
                               6369                 :                :     int         i_oid;
                               6370                 :                :     int         i_collname;
                               6371                 :                :     int         i_collnamespace;
                               6372                 :                :     int         i_collowner;
                               6373                 :                :     int         i_collencoding;
                               6374                 :                : 
 4925 peter_e@gmx.net          6375                 :            185 :     query = createPQExpBuffer();
                               6376                 :                : 
                               6377                 :                :     /*
                               6378                 :                :      * find all collations, including builtin collations; we filter out
                               6379                 :                :      * system-defined collations at dump-out time.
                               6380                 :                :      */
                               6381                 :                : 
 1096 drowley@postgresql.o     6382                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
                               6383                 :                :                          "collnamespace, "
                               6384                 :                :                          "collowner, "
                               6385                 :                :                          "collencoding "
                               6386                 :                :                          "FROM pg_collation");
                               6387                 :                : 
 4960 rhaas@postgresql.org     6388                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6389                 :                : 
 5320 peter_e@gmx.net          6390                 :            185 :     ntups = PQntuples(res);
                               6391                 :                : 
 5034 bruce@momjian.us         6392                 :            185 :     collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
                               6393                 :                : 
 5320 peter_e@gmx.net          6394                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               6395                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6396                 :            185 :     i_collname = PQfnumber(res, "collname");
                               6397                 :            185 :     i_collnamespace = PQfnumber(res, "collnamespace");
 1345 tgl@sss.pgh.pa.us        6398                 :            185 :     i_collowner = PQfnumber(res, "collowner");
   37 noah@leadboat.com        6399                 :            185 :     i_collencoding = PQfnumber(res, "collencoding");
                               6400                 :                : 
 5320 peter_e@gmx.net          6401         [ +  + ]:         281138 :     for (i = 0; i < ntups; i++)
                               6402                 :                :     {
                               6403                 :         280953 :         collinfo[i].dobj.objType = DO_COLLATION;
                               6404                 :         280953 :         collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6405                 :         280953 :         collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6406                 :         280953 :         AssignDumpId(&collinfo[i].dobj);
 5034 bruce@momjian.us         6407                 :         280953 :         collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
 4961 rhaas@postgresql.org     6408                 :         561906 :         collinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6409                 :         280953 :             findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
 1345 tgl@sss.pgh.pa.us        6410                 :         280953 :         collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
   37 noah@leadboat.com        6411                 :         280953 :         collinfo[i].collencoding = atoi(PQgetvalue(res, i, i_collencoding));
                               6412                 :                : 
                               6413                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6414                 :         280953 :         selectDumpableObject(&(collinfo[i].dobj), fout);
                               6415                 :                :     }
                               6416                 :                : 
 5320 peter_e@gmx.net          6417                 :            185 :     PQclear(res);
                               6418                 :                : 
                               6419                 :            185 :     destroyPQExpBuffer(query);
                               6420                 :            185 : }
                               6421                 :                : 
                               6422                 :                : /*
                               6423                 :                :  * getConversions:
                               6424                 :                :  *    get information about all conversions in the system catalogs
                               6425                 :                :  */
                               6426                 :                : void
  431 nathan@postgresql.or     6427                 :            185 : getConversions(Archive *fout)
                               6428                 :                : {
                               6429                 :                :     PGresult   *res;
                               6430                 :                :     int         ntups;
                               6431                 :                :     int         i;
                               6432                 :                :     PQExpBuffer query;
                               6433                 :                :     ConvInfo   *convinfo;
                               6434                 :                :     int         i_tableoid;
                               6435                 :                :     int         i_oid;
                               6436                 :                :     int         i_conname;
                               6437                 :                :     int         i_connamespace;
                               6438                 :                :     int         i_conowner;
                               6439                 :                : 
 4241 sfrost@snowman.net       6440                 :            185 :     query = createPQExpBuffer();
                               6441                 :                : 
                               6442                 :                :     /*
                               6443                 :                :      * find all conversions, including builtin conversions; we filter out
                               6444                 :                :      * system-defined conversions at dump-out time.
                               6445                 :                :      */
                               6446                 :                : 
 1096 drowley@postgresql.o     6447                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
                               6448                 :                :                          "connamespace, "
                               6449                 :                :                          "conowner "
                               6450                 :                :                          "FROM pg_conversion");
                               6451                 :                : 
 4960 rhaas@postgresql.org     6452                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6453                 :                : 
 7960 tgl@sss.pgh.pa.us        6454                 :            185 :     ntups = PQntuples(res);
                               6455                 :                : 
 5034 bruce@momjian.us         6456                 :            185 :     convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
                               6457                 :                : 
 7945 tgl@sss.pgh.pa.us        6458                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 7960                          6459                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6460                 :            185 :     i_conname = PQfnumber(res, "conname");
                               6461                 :            185 :     i_connamespace = PQfnumber(res, "connamespace");
 1345                          6462                 :            185 :     i_conowner = PQfnumber(res, "conowner");
                               6463                 :                : 
 7960                          6464         [ +  + ]:          23916 :     for (i = 0; i < ntups; i++)
                               6465                 :                :     {
 7945                          6466                 :          23731 :         convinfo[i].dobj.objType = DO_CONVERSION;
                               6467                 :          23731 :         convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6468                 :          23731 :         convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6469                 :          23731 :         AssignDumpId(&convinfo[i].dobj);
 5034 bruce@momjian.us         6470                 :          23731 :         convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 4961 rhaas@postgresql.org     6471                 :          47462 :         convinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6472                 :          23731 :             findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
 1345 tgl@sss.pgh.pa.us        6473                 :          23731 :         convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
                               6474                 :                : 
                               6475                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6476                 :          23731 :         selectDumpableObject(&(convinfo[i].dobj), fout);
                               6477                 :                :     }
                               6478                 :                : 
 7960 tgl@sss.pgh.pa.us        6479                 :            185 :     PQclear(res);
                               6480                 :                : 
                               6481                 :            185 :     destroyPQExpBuffer(query);
                               6482                 :            185 : }
                               6483                 :                : 
                               6484                 :                : /*
                               6485                 :                :  * getAccessMethods:
                               6486                 :                :  *    get information about all user-defined access methods
                               6487                 :                :  */
                               6488                 :                : void
  431 nathan@postgresql.or     6489                 :            185 : getAccessMethods(Archive *fout)
                               6490                 :                : {
                               6491                 :                :     PGresult   *res;
                               6492                 :                :     int         ntups;
                               6493                 :                :     int         i;
                               6494                 :                :     PQExpBuffer query;
                               6495                 :                :     AccessMethodInfo *aminfo;
                               6496                 :                :     int         i_tableoid;
                               6497                 :                :     int         i_oid;
                               6498                 :                :     int         i_amname;
                               6499                 :                :     int         i_amhandler;
                               6500                 :                :     int         i_amtype;
                               6501                 :                : 
 3454 alvherre@alvh.no-ip.     6502                 :            185 :     query = createPQExpBuffer();
                               6503                 :                : 
                               6504                 :                :     /*
                               6505                 :                :      * Select all access methods from pg_am table.  v9.6 introduced CREATE
                               6506                 :                :      * ACCESS METHOD, so earlier versions usually have only built-in access
                               6507                 :                :      * methods.  v9.6 also changed the access method API, replacing dozens of
                               6508                 :                :      * pg_am columns with amhandler.  Even if a user created an access method
                               6509                 :                :      * by "INSERT INTO pg_am", we have no way to translate pre-v9.6 pg_am
                               6510                 :                :      * columns to a v9.6+ CREATE ACCESS METHOD.  Hence, before v9.6, read
                               6511                 :                :      * pg_am just to facilitate findAccessMethodByOid() providing the
                               6512                 :                :      * OID-to-name mapping.
                               6513                 :                :      */
   37 noah@leadboat.com        6514                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, ");
                               6515         [ +  - ]:            185 :     if (fout->remoteVersion >= 90600)
                               6516                 :            185 :         appendPQExpBufferStr(query,
                               6517                 :                :                              "amtype, "
                               6518                 :                :                              "amhandler::pg_catalog.regproc AS amhandler ");
                               6519                 :                :     else
   37 noah@leadboat.com        6520                 :UBC           0 :         appendPQExpBufferStr(query,
                               6521                 :                :                              "'i'::pg_catalog.\"char\" AS amtype, "
                               6522                 :                :                              "'-'::pg_catalog.regproc AS amhandler ");
   37 noah@leadboat.com        6523                 :CBC         185 :     appendPQExpBufferStr(query, "FROM pg_am");
                               6524                 :                : 
 3454 alvherre@alvh.no-ip.     6525                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6526                 :                : 
                               6527                 :            185 :     ntups = PQntuples(res);
                               6528                 :                : 
                               6529                 :            185 :     aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
                               6530                 :                : 
                               6531                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               6532                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6533                 :            185 :     i_amname = PQfnumber(res, "amname");
                               6534                 :            185 :     i_amhandler = PQfnumber(res, "amhandler");
                               6535                 :            185 :     i_amtype = PQfnumber(res, "amtype");
                               6536                 :                : 
                               6537         [ +  + ]:           1614 :     for (i = 0; i < ntups; i++)
                               6538                 :                :     {
                               6539                 :           1429 :         aminfo[i].dobj.objType = DO_ACCESS_METHOD;
                               6540                 :           1429 :         aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6541                 :           1429 :         aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6542                 :           1429 :         AssignDumpId(&aminfo[i].dobj);
                               6543                 :           1429 :         aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
                               6544                 :           1429 :         aminfo[i].dobj.namespace = NULL;
                               6545                 :           1429 :         aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
                               6546                 :           1429 :         aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
                               6547                 :                : 
                               6548                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6549                 :           1429 :         selectDumpableAccessMethod(&(aminfo[i]), fout);
                               6550                 :                :     }
                               6551                 :                : 
 3454 alvherre@alvh.no-ip.     6552                 :            185 :     PQclear(res);
                               6553                 :                : 
                               6554                 :            185 :     destroyPQExpBuffer(query);
                               6555                 :            185 : }
                               6556                 :                : 
                               6557                 :                : 
                               6558                 :                : /*
                               6559                 :                :  * getOpclasses:
                               6560                 :                :  *    get information about all opclasses in the system catalogs
                               6561                 :                :  */
                               6562                 :                : void
  431 nathan@postgresql.or     6563                 :            185 : getOpclasses(Archive *fout)
                               6564                 :                : {
                               6565                 :                :     PGresult   *res;
                               6566                 :                :     int         ntups;
                               6567                 :                :     int         i;
 8439 tgl@sss.pgh.pa.us        6568                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               6569                 :                :     OpclassInfo *opcinfo;
                               6570                 :                :     int         i_tableoid;
                               6571                 :                :     int         i_oid;
                               6572                 :                :     int         i_opcmethod;
                               6573                 :                :     int         i_opcname;
                               6574                 :                :     int         i_opcnamespace;
                               6575                 :                :     int         i_opcowner;
                               6576                 :                : 
                               6577                 :                :     /*
                               6578                 :                :      * find all opclasses, including builtin opclasses; we filter out
                               6579                 :                :      * system-defined opclasses at dump-out time.
                               6580                 :                :      */
                               6581                 :                : 
   37 noah@leadboat.com        6582                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opcmethod, opcname, "
                               6583                 :                :                          "opcnamespace, "
                               6584                 :                :                          "opcowner "
                               6585                 :                :                          "FROM pg_opclass");
                               6586                 :                : 
 4960 rhaas@postgresql.org     6587                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6588                 :                : 
 8439 tgl@sss.pgh.pa.us        6589                 :            185 :     ntups = PQntuples(res);
                               6590                 :                : 
 5034 bruce@momjian.us         6591                 :            185 :     opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
                               6592                 :                : 
 7945 tgl@sss.pgh.pa.us        6593                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 8439                          6594                 :            185 :     i_oid = PQfnumber(res, "oid");
   37 noah@leadboat.com        6595                 :            185 :     i_opcmethod = PQfnumber(res, "opcmethod");
 8439 tgl@sss.pgh.pa.us        6596                 :            185 :     i_opcname = PQfnumber(res, "opcname");
                               6597                 :            185 :     i_opcnamespace = PQfnumber(res, "opcnamespace");
 1345                          6598                 :            185 :     i_opcowner = PQfnumber(res, "opcowner");
                               6599                 :                : 
 8439                          6600         [ +  + ]:          33104 :     for (i = 0; i < ntups; i++)
                               6601                 :                :     {
 7945                          6602                 :          32919 :         opcinfo[i].dobj.objType = DO_OPCLASS;
                               6603                 :          32919 :         opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6604                 :          32919 :         opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6605                 :          32919 :         AssignDumpId(&opcinfo[i].dobj);
 5034 bruce@momjian.us         6606                 :          32919 :         opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
 4961 rhaas@postgresql.org     6607                 :          65838 :         opcinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6608                 :          32919 :             findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
   37 noah@leadboat.com        6609                 :          32919 :         opcinfo[i].opcmethod = atooid(PQgetvalue(res, i, i_opcmethod));
 1345 tgl@sss.pgh.pa.us        6610                 :          32919 :         opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
                               6611                 :                : 
                               6612                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6613                 :          32919 :         selectDumpableObject(&(opcinfo[i].dobj), fout);
                               6614                 :                :     }
                               6615                 :                : 
 8439 tgl@sss.pgh.pa.us        6616                 :            185 :     PQclear(res);
                               6617                 :                : 
                               6618                 :            185 :     destroyPQExpBuffer(query);
                               6619                 :            185 : }
                               6620                 :                : 
                               6621                 :                : /*
                               6622                 :                :  * getOpfamilies:
                               6623                 :                :  *    get information about all opfamilies in the system catalogs
                               6624                 :                :  */
                               6625                 :                : void
  431 nathan@postgresql.or     6626                 :            185 : getOpfamilies(Archive *fout)
                               6627                 :                : {
                               6628                 :                :     PGresult   *res;
                               6629                 :                :     int         ntups;
                               6630                 :                :     int         i;
                               6631                 :                :     PQExpBuffer query;
                               6632                 :                :     OpfamilyInfo *opfinfo;
                               6633                 :                :     int         i_tableoid;
                               6634                 :                :     int         i_oid;
                               6635                 :                :     int         i_opfmethod;
                               6636                 :                :     int         i_opfname;
                               6637                 :                :     int         i_opfnamespace;
                               6638                 :                :     int         i_opfowner;
                               6639                 :                : 
 6801 tgl@sss.pgh.pa.us        6640                 :            185 :     query = createPQExpBuffer();
                               6641                 :                : 
                               6642                 :                :     /*
                               6643                 :                :      * find all opfamilies, including builtin opfamilies; we filter out
                               6644                 :                :      * system-defined opfamilies at dump-out time.
                               6645                 :                :      */
                               6646                 :                : 
   37 noah@leadboat.com        6647                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opfmethod, opfname, "
                               6648                 :                :                          "opfnamespace, "
                               6649                 :                :                          "opfowner "
                               6650                 :                :                          "FROM pg_opfamily");
                               6651                 :                : 
 4960 rhaas@postgresql.org     6652                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6653                 :                : 
 6801 tgl@sss.pgh.pa.us        6654                 :            185 :     ntups = PQntuples(res);
                               6655                 :                : 
 5034 bruce@momjian.us         6656                 :            185 :     opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
                               6657                 :                : 
 6801 tgl@sss.pgh.pa.us        6658                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               6659                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6660                 :            185 :     i_opfname = PQfnumber(res, "opfname");
   37 noah@leadboat.com        6661                 :            185 :     i_opfmethod = PQfnumber(res, "opfmethod");
 6801 tgl@sss.pgh.pa.us        6662                 :            185 :     i_opfnamespace = PQfnumber(res, "opfnamespace");
 1345                          6663                 :            185 :     i_opfowner = PQfnumber(res, "opfowner");
                               6664                 :                : 
 6801                          6665         [ +  + ]:          27346 :     for (i = 0; i < ntups; i++)
                               6666                 :                :     {
                               6667                 :          27161 :         opfinfo[i].dobj.objType = DO_OPFAMILY;
                               6668                 :          27161 :         opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6669                 :          27161 :         opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6670                 :          27161 :         AssignDumpId(&opfinfo[i].dobj);
 5034 bruce@momjian.us         6671                 :          27161 :         opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
 4961 rhaas@postgresql.org     6672                 :          54322 :         opfinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6673                 :          27161 :             findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
   37 noah@leadboat.com        6674                 :          27161 :         opfinfo[i].opfmethod = atooid(PQgetvalue(res, i, i_opfmethod));
 1345 tgl@sss.pgh.pa.us        6675                 :          27161 :         opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
                               6676                 :                : 
                               6677                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6678                 :          27161 :         selectDumpableObject(&(opfinfo[i].dobj), fout);
                               6679                 :                :     }
                               6680                 :                : 
 6801 tgl@sss.pgh.pa.us        6681                 :            185 :     PQclear(res);
                               6682                 :                : 
                               6683                 :            185 :     destroyPQExpBuffer(query);
                               6684                 :            185 : }
                               6685                 :                : 
                               6686                 :                : /*
                               6687                 :                :  * getAggregates:
                               6688                 :                :  *    get information about all user-defined aggregates in the system catalogs
                               6689                 :                :  */
                               6690                 :                : void
  431 nathan@postgresql.or     6691                 :            185 : getAggregates(Archive *fout)
                               6692                 :                : {
 3524 tgl@sss.pgh.pa.us        6693                 :            185 :     DumpOptions *dopt = fout->dopt;
                               6694                 :                :     PGresult   *res;
                               6695                 :                :     int         ntups;
                               6696                 :                :     int         i;
 9278 bruce@momjian.us         6697                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               6698                 :                :     AggInfo    *agginfo;
                               6699                 :                :     int         i_tableoid;
                               6700                 :                :     int         i_oid;
                               6701                 :                :     int         i_aggname;
                               6702                 :                :     int         i_aggnamespace;
                               6703                 :                :     int         i_pronargs;
                               6704                 :                :     int         i_proargtypes;
                               6705                 :                :     int         i_proowner;
                               6706                 :                :     int         i_aggacl;
                               6707                 :                :     int         i_acldefault;
                               6708                 :                : 
                               6709                 :                :     /*
                               6710                 :                :      * Find all interesting aggregates.  See comment in getFuncs() for the
                               6711                 :                :      * rationale behind the filtering logic.
                               6712                 :                :      */
 3440 sfrost@snowman.net       6713         [ +  - ]:            185 :     if (fout->remoteVersion >= 90600)
                               6714                 :                :     {
                               6715                 :                :         const char *agg_check;
                               6716                 :                : 
 2745 peter_e@gmx.net          6717                 :            370 :         agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
                               6718         [ +  - ]:            185 :                      : "p.proisagg");
                               6719                 :                : 
 3440 sfrost@snowman.net       6720                 :            185 :         appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
                               6721                 :                :                           "p.proname AS aggname, "
                               6722                 :                :                           "p.pronamespace AS aggnamespace, "
                               6723                 :                :                           "p.pronargs, p.proargtypes, "
                               6724                 :                :                           "p.proowner, "
                               6725                 :                :                           "p.proacl AS aggacl, "
                               6726                 :                :                           "acldefault('f', p.proowner) AS acldefault "
                               6727                 :                :                           "FROM pg_proc p "
                               6728                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6729                 :                :                           "(p.oid = pip.objoid "
                               6730                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6731                 :                :                           "AND pip.objsubid = 0) "
                               6732                 :                :                           "WHERE %s AND ("
                               6733                 :                :                           "p.pronamespace != "
                               6734                 :                :                           "(SELECT oid FROM pg_namespace "
                               6735                 :                :                           "WHERE nspname = 'pg_catalog') OR "
                               6736                 :                :                           "p.proacl IS DISTINCT FROM pip.initprivs",
                               6737                 :                :                           agg_check);
                               6738         [ +  + ]:            185 :         if (dopt->binary_upgrade)
                               6739                 :             36 :             appendPQExpBufferStr(query,
                               6740                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6741                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6742                 :                :                                  "objid = p.oid AND "
                               6743                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6744                 :                :                                  "deptype = 'e')");
                               6745                 :            185 :         appendPQExpBufferChar(query, ')');
                               6746                 :                :     }
                               6747                 :                :     else
                               6748                 :                :     {
 1096 drowley@postgresql.o     6749                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
                               6750                 :                :                              "pronamespace AS aggnamespace, "
                               6751                 :                :                              "pronargs, proargtypes, "
                               6752                 :                :                              "proowner, "
                               6753                 :                :                              "proacl AS aggacl, "
                               6754                 :                :                              "acldefault('f', proowner) AS acldefault "
                               6755                 :                :                              "FROM pg_proc p "
                               6756                 :                :                              "WHERE proisagg AND ("
                               6757                 :                :                              "pronamespace != "
                               6758                 :                :                              "(SELECT oid FROM pg_namespace "
                               6759                 :                :                              "WHERE nspname = 'pg_catalog')");
 1370 tgl@sss.pgh.pa.us        6760         [ #  # ]:              0 :         if (dopt->binary_upgrade)
                               6761                 :              0 :             appendPQExpBufferStr(query,
                               6762                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6763                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6764                 :                :                                  "objid = p.oid AND "
                               6765                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6766                 :                :                                  "deptype = 'e')");
                               6767                 :              0 :         appendPQExpBufferChar(query, ')');
                               6768                 :                :     }
                               6769                 :                : 
 4960 rhaas@postgresql.org     6770                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6771                 :                : 
10226 bruce@momjian.us         6772                 :            185 :     ntups = PQntuples(res);
                               6773                 :                : 
 5034                          6774                 :            185 :     agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
                               6775                 :                : 
 7945 tgl@sss.pgh.pa.us        6776                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 8520                          6777                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6778                 :            185 :     i_aggname = PQfnumber(res, "aggname");
                               6779                 :            185 :     i_aggnamespace = PQfnumber(res, "aggnamespace");
 6981                          6780                 :            185 :     i_pronargs = PQfnumber(res, "pronargs");
                               6781                 :            185 :     i_proargtypes = PQfnumber(res, "proargtypes");
 1345                          6782                 :            185 :     i_proowner = PQfnumber(res, "proowner");
 8511 peter_e@gmx.net          6783                 :            185 :     i_aggacl = PQfnumber(res, "aggacl");
 1370 tgl@sss.pgh.pa.us        6784                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
                               6785                 :                : 
10226 bruce@momjian.us         6786         [ +  + ]:            590 :     for (i = 0; i < ntups; i++)
                               6787                 :                :     {
 7945 tgl@sss.pgh.pa.us        6788                 :            405 :         agginfo[i].aggfn.dobj.objType = DO_AGG;
                               6789                 :            405 :         agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6790                 :            405 :         agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6791                 :            405 :         AssignDumpId(&agginfo[i].aggfn.dobj);
 5034 bruce@momjian.us         6792                 :            405 :         agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
 4961 rhaas@postgresql.org     6793                 :            810 :         agginfo[i].aggfn.dobj.namespace =
 1838 peter@eisentraut.org     6794                 :            405 :             findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
 1370 tgl@sss.pgh.pa.us        6795                 :            405 :         agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
                               6796                 :            405 :         agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6797                 :            405 :         agginfo[i].aggfn.dacl.privtype = 0;
                               6798                 :            405 :         agginfo[i].aggfn.dacl.initprivs = NULL;
 1345                          6799                 :            405 :         agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 2999                          6800                 :            405 :         agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
                               6801                 :            405 :         agginfo[i].aggfn.prorettype = InvalidOid;   /* not saved */
 6981                          6802                 :            405 :         agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               6803         [ +  + ]:            405 :         if (agginfo[i].aggfn.nargs == 0)
                               6804                 :             56 :             agginfo[i].aggfn.argtypes = NULL;
                               6805                 :                :         else
                               6806                 :                :         {
 5034 bruce@momjian.us         6807                 :            349 :             agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
 3251 tgl@sss.pgh.pa.us        6808                 :            349 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               6809                 :            349 :                           agginfo[i].aggfn.argtypes,
                               6810                 :            349 :                           agginfo[i].aggfn.nargs);
                               6811                 :                :         }
  825                          6812                 :            405 :         agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
                               6813                 :                : 
                               6814                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       6815                 :            405 :         selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
                               6816                 :                : 
                               6817                 :                :         /* Mark whether aggregate has an ACL */
 1370 tgl@sss.pgh.pa.us        6818         [ +  + ]:            405 :         if (!PQgetisnull(res, i, i_aggacl))
                               6819                 :             25 :             agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
                               6820                 :                :     }
                               6821                 :                : 
 8520                          6822                 :            185 :     PQclear(res);
                               6823                 :                : 
                               6824                 :            185 :     destroyPQExpBuffer(query);
                               6825                 :            185 : }
                               6826                 :                : 
                               6827                 :                : /*
                               6828                 :                :  * getFuncs:
                               6829                 :                :  *    get information about all user-defined functions in the system catalogs
                               6830                 :                :  */
                               6831                 :                : void
  431 nathan@postgresql.or     6832                 :            185 : getFuncs(Archive *fout)
                               6833                 :                : {
 3524 tgl@sss.pgh.pa.us        6834                 :            185 :     DumpOptions *dopt = fout->dopt;
                               6835                 :                :     PGresult   *res;
                               6836                 :                :     int         ntups;
                               6837                 :                :     int         i;
 8520                          6838                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               6839                 :                :     FuncInfo   *finfo;
                               6840                 :                :     int         i_tableoid;
                               6841                 :                :     int         i_oid;
                               6842                 :                :     int         i_proname;
                               6843                 :                :     int         i_pronamespace;
                               6844                 :                :     int         i_proowner;
                               6845                 :                :     int         i_prolang;
                               6846                 :                :     int         i_pronargs;
                               6847                 :                :     int         i_proargtypes;
                               6848                 :                :     int         i_prorettype;
                               6849                 :                :     int         i_proacl;
                               6850                 :                :     int         i_acldefault;
                               6851                 :                : 
                               6852                 :                :     /*
                               6853                 :                :      * Find all interesting functions.  This is a bit complicated:
                               6854                 :                :      *
                               6855                 :                :      * 1. Always exclude aggregates; those are handled elsewhere.
                               6856                 :                :      *
                               6857                 :                :      * 2. Always exclude functions that are internally dependent on something
                               6858                 :                :      * else, since presumably those will be created as a result of creating
                               6859                 :                :      * the something else.  This currently acts only to suppress constructor
                               6860                 :                :      * functions for range types.  Note this is OK only because the
                               6861                 :                :      * constructors don't have any dependencies the range type doesn't have;
                               6862                 :                :      * otherwise we might not get creation ordering correct.
                               6863                 :                :      *
                               6864                 :                :      * 3. Otherwise, we normally exclude functions in pg_catalog.  However, if
                               6865                 :                :      * they're members of extensions and we are in binary-upgrade mode then
                               6866                 :                :      * include them, since we want to dump extension members individually in
                               6867                 :                :      * that mode.  Also, if they are used by casts or transforms then we need
                               6868                 :                :      * to gather the information about them, though they won't be dumped if
                               6869                 :                :      * they are built-in.  Also, in 9.6 and up, include functions in
                               6870                 :                :      * pg_catalog if they have an ACL different from what's shown in
                               6871                 :                :      * pg_init_privs (so we have to join to pg_init_privs; annoying).
                               6872                 :                :      */
 3440 sfrost@snowman.net       6873         [ +  - ]:            185 :     if (fout->remoteVersion >= 90600)
                               6874                 :                :     {
                               6875                 :                :         const char *not_agg_check;
                               6876                 :                : 
 2745 peter_e@gmx.net          6877                 :            370 :         not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
                               6878         [ +  - ]:            185 :                          : "NOT p.proisagg");
                               6879                 :                : 
 3440 sfrost@snowman.net       6880                 :            185 :         appendPQExpBuffer(query,
                               6881                 :                :                           "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
                               6882                 :                :                           "p.pronargs, p.proargtypes, p.prorettype, "
                               6883                 :                :                           "p.proacl, "
                               6884                 :                :                           "acldefault('f', p.proowner) AS acldefault, "
                               6885                 :                :                           "p.pronamespace, "
                               6886                 :                :                           "p.proowner "
                               6887                 :                :                           "FROM pg_proc p "
                               6888                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6889                 :                :                           "(p.oid = pip.objoid "
                               6890                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6891                 :                :                           "AND pip.objsubid = 0) "
                               6892                 :                :                           "WHERE %s"
                               6893                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6894                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               6895                 :                :                           "objid = p.oid AND deptype = 'i')"
                               6896                 :                :                           "\n  AND ("
                               6897                 :                :                           "\n  pronamespace != "
                               6898                 :                :                           "(SELECT oid FROM pg_namespace "
                               6899                 :                :                           "WHERE nspname = 'pg_catalog')"
                               6900                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               6901                 :                :                           "\n  WHERE pg_cast.oid > %u "
                               6902                 :                :                           "\n  AND p.oid = pg_cast.castfunc)"
                               6903                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               6904                 :                :                           "\n  WHERE pg_transform.oid > %u AND "
                               6905                 :                :                           "\n  (p.oid = pg_transform.trffromsql"
                               6906                 :                :                           "\n  OR p.oid = pg_transform.trftosql))",
                               6907                 :                :                           not_agg_check,
                               6908                 :                :                           g_last_builtin_oid,
                               6909                 :                :                           g_last_builtin_oid);
                               6910         [ +  + ]:            185 :         if (dopt->binary_upgrade)
                               6911                 :             36 :             appendPQExpBufferStr(query,
                               6912                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6913                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6914                 :                :                                  "objid = p.oid AND "
                               6915                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6916                 :                :                                  "deptype = 'e')");
 3270 tgl@sss.pgh.pa.us        6917                 :            185 :         appendPQExpBufferStr(query,
                               6918                 :                :                              "\n  OR p.proacl IS DISTINCT FROM pip.initprivs");
 3440 sfrost@snowman.net       6919                 :            185 :         appendPQExpBufferChar(query, ')');
                               6920                 :                :     }
                               6921                 :                :     else
                               6922                 :                :     {
 8520 tgl@sss.pgh.pa.us        6923                 :UBC           0 :         appendPQExpBuffer(query,
                               6924                 :                :                           "SELECT tableoid, oid, proname, prolang, "
                               6925                 :                :                           "pronargs, proargtypes, prorettype, proacl, "
                               6926                 :                :                           "acldefault('f', proowner) AS acldefault, "
                               6927                 :                :                           "pronamespace, "
                               6928                 :                :                           "proowner "
                               6929                 :                :                           "FROM pg_proc p "
                               6930                 :                :                           "WHERE NOT proisagg"
                               6931                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6932                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               6933                 :                :                           "objid = p.oid AND deptype = 'i')"
                               6934                 :                :                           "\n  AND ("
                               6935                 :                :                           "\n  pronamespace != "
                               6936                 :                :                           "(SELECT oid FROM pg_namespace "
                               6937                 :                :                           "WHERE nspname = 'pg_catalog')"
                               6938                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               6939                 :                :                           "\n  WHERE pg_cast.oid > '%u'::oid"
                               6940                 :                :                           "\n  AND p.oid = pg_cast.castfunc)",
                               6941                 :                :                           g_last_builtin_oid);
                               6942                 :                : 
 3181 sfrost@snowman.net       6943         [ #  # ]:              0 :         if (fout->remoteVersion >= 90500)
                               6944                 :              0 :             appendPQExpBuffer(query,
                               6945                 :                :                               "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               6946                 :                :                               "\n  WHERE pg_transform.oid > '%u'::oid"
                               6947                 :                :                               "\n  AND (p.oid = pg_transform.trffromsql"
                               6948                 :                :                               "\n  OR p.oid = pg_transform.trftosql))",
                               6949                 :                :                               g_last_builtin_oid);
                               6950                 :                : 
 1362 tgl@sss.pgh.pa.us        6951         [ #  # ]:              0 :         if (dopt->binary_upgrade)
 4310 heikki.linnakangas@i     6952                 :              0 :             appendPQExpBufferStr(query,
                               6953                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6954                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6955                 :                :                                  "objid = p.oid AND "
                               6956                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6957                 :                :                                  "deptype = 'e')");
                               6958                 :              0 :         appendPQExpBufferChar(query, ')');
                               6959                 :                :     }
                               6960                 :                : 
 4960 rhaas@postgresql.org     6961                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6962                 :                : 
 8520 tgl@sss.pgh.pa.us        6963                 :            185 :     ntups = PQntuples(res);
                               6964                 :                : 
 4722                          6965                 :            185 :     finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
                               6966                 :                : 
 7945                          6967                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 8520                          6968                 :            185 :     i_oid = PQfnumber(res, "oid");
                               6969                 :            185 :     i_proname = PQfnumber(res, "proname");
                               6970                 :            185 :     i_pronamespace = PQfnumber(res, "pronamespace");
 1345                          6971                 :            185 :     i_proowner = PQfnumber(res, "proowner");
 8520                          6972                 :            185 :     i_prolang = PQfnumber(res, "prolang");
                               6973                 :            185 :     i_pronargs = PQfnumber(res, "pronargs");
                               6974                 :            185 :     i_proargtypes = PQfnumber(res, "proargtypes");
                               6975                 :            185 :     i_prorettype = PQfnumber(res, "prorettype");
 8511 peter_e@gmx.net          6976                 :            185 :     i_proacl = PQfnumber(res, "proacl");
 1370 tgl@sss.pgh.pa.us        6977                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
                               6978                 :                : 
 8520                          6979         [ +  + ]:           4995 :     for (i = 0; i < ntups; i++)
                               6980                 :                :     {
 7945                          6981                 :           4810 :         finfo[i].dobj.objType = DO_FUNC;
                               6982                 :           4810 :         finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6983                 :           4810 :         finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6984                 :           4810 :         AssignDumpId(&finfo[i].dobj);
 5034 bruce@momjian.us         6985                 :           4810 :         finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
 7266                          6986                 :           9620 :         finfo[i].dobj.namespace =
 1838 peter@eisentraut.org     6987                 :           4810 :             findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
 1370 tgl@sss.pgh.pa.us        6988                 :           4810 :         finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
                               6989                 :           4810 :         finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6990                 :           4810 :         finfo[i].dacl.privtype = 0;
                               6991                 :           4810 :         finfo[i].dacl.initprivs = NULL;
 1345                          6992                 :           4810 :         finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 8520                          6993                 :           4810 :         finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
 7945                          6994                 :           4810 :         finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
 8520                          6995                 :           4810 :         finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               6996         [ +  + ]:           4810 :         if (finfo[i].nargs == 0)
                               6997                 :           1094 :             finfo[i].argtypes = NULL;
                               6998                 :                :         else
                               6999                 :                :         {
 5034 bruce@momjian.us         7000                 :           3716 :             finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
 7945 tgl@sss.pgh.pa.us        7001                 :           3716 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               7002                 :           3716 :                           finfo[i].argtypes, finfo[i].nargs);
                               7003                 :                :         }
  825                          7004                 :           4810 :         finfo[i].postponed_def = false; /* might get set during sort */
                               7005                 :                : 
                               7006                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       7007                 :           4810 :         selectDumpableObject(&(finfo[i].dobj), fout);
                               7008                 :                : 
                               7009                 :                :         /* Mark whether function has an ACL */
 1370 tgl@sss.pgh.pa.us        7010         [ +  + ]:           4810 :         if (!PQgetisnull(res, i, i_proacl))
                               7011                 :            152 :             finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               7012                 :                :     }
                               7013                 :                : 
 8520                          7014                 :            185 :     PQclear(res);
                               7015                 :                : 
                               7016                 :            185 :     destroyPQExpBuffer(query);
                               7017                 :            185 : }
                               7018                 :                : 
                               7019                 :                : /*
                               7020                 :                :  * getRelationStatistics
                               7021                 :                :  *    register the statistics object as a dependent of the relation.
                               7022                 :                :  *
                               7023                 :                :  * reltuples is passed as a string to avoid complexities in converting from/to
                               7024                 :                :  * floating point.
                               7025                 :                :  */
                               7026                 :                : static RelStatsInfo *
  193 jdavis@postgresql.or     7027                 :          10089 : getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
                               7028                 :                :                       char *reltuples, int32 relallvisible,
                               7029                 :                :                       int32 relallfrozen, char relkind,
                               7030                 :                :                       char **indAttNames, int nindAttNames)
                               7031                 :                : {
  198                          7032         [ +  + ]:          10089 :     if (!fout->dopt->dumpStatistics)
                               7033                 :           6036 :         return NULL;
                               7034                 :                : 
                               7035   [ +  +  +  + ]:           4053 :     if ((relkind == RELKIND_RELATION) ||
                               7036         [ +  + ]:           1707 :         (relkind == RELKIND_PARTITIONED_TABLE) ||
                               7037         [ +  + ]:           1047 :         (relkind == RELKIND_INDEX) ||
                               7038         [ +  + ]:            687 :         (relkind == RELKIND_PARTITIONED_INDEX) ||
   80 fujii@postgresql.org     7039         [ +  + ]:            299 :         (relkind == RELKIND_MATVIEW ||
                               7040                 :                :          relkind == RELKIND_FOREIGN_TABLE))
                               7041                 :                :     {
  198 jdavis@postgresql.or     7042                 :           3792 :         RelStatsInfo *info = pg_malloc0(sizeof(RelStatsInfo));
                               7043                 :           3792 :         DumpableObject *dobj = &info->dobj;
                               7044                 :                : 
                               7045                 :           3792 :         dobj->objType = DO_REL_STATS;
                               7046                 :           3792 :         dobj->catId.tableoid = 0;
                               7047                 :           3792 :         dobj->catId.oid = 0;
                               7048                 :           3792 :         AssignDumpId(dobj);
                               7049                 :           3792 :         dobj->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               7050                 :           3792 :         dobj->dependencies[0] = rel->dumpId;
                               7051                 :           3792 :         dobj->nDeps = 1;
                               7052                 :           3792 :         dobj->allocDeps = 1;
                               7053                 :           3792 :         dobj->components |= DUMP_COMPONENT_STATISTICS;
                               7054                 :           3792 :         dobj->name = pg_strdup(rel->name);
                               7055                 :           3792 :         dobj->namespace = rel->namespace;
  193                          7056                 :           3792 :         info->relpages = relpages;
  182                          7057                 :           3792 :         info->reltuples = pstrdup(reltuples);
  193                          7058                 :           3792 :         info->relallvisible = relallvisible;
  160                          7059                 :           3792 :         info->relallfrozen = relallfrozen;
  198                          7060                 :           3792 :         info->relkind = relkind;
  192 tgl@sss.pgh.pa.us        7061                 :           3792 :         info->indAttNames = indAttNames;
                               7062                 :           3792 :         info->nindAttNames = nindAttNames;
                               7063                 :                : 
                               7064                 :                :         /*
                               7065                 :                :          * Ordinarily, stats go in SECTION_DATA for tables and
                               7066                 :                :          * SECTION_POST_DATA for indexes.
                               7067                 :                :          *
                               7068                 :                :          * However, the section may be updated later for materialized view
                               7069                 :                :          * stats. REFRESH MATERIALIZED VIEW replaces the storage and resets
                               7070                 :                :          * the stats, so the stats must be restored after the data. Also, the
                               7071                 :                :          * materialized view definition may be postponed to SECTION_POST_DATA
                               7072                 :                :          * (see repairMatViewBoundaryMultiLoop()).
                               7073                 :                :          */
  162 jdavis@postgresql.or     7074      [ +  +  - ]:           3792 :         switch (info->relkind)
                               7075                 :                :         {
                               7076                 :           2772 :             case RELKIND_RELATION:
                               7077                 :                :             case RELKIND_PARTITIONED_TABLE:
                               7078                 :                :             case RELKIND_MATVIEW:
                               7079                 :                :             case RELKIND_FOREIGN_TABLE:
                               7080                 :           2772 :                 info->section = SECTION_DATA;
                               7081                 :           2772 :                 break;
                               7082                 :           1020 :             case RELKIND_INDEX:
                               7083                 :                :             case RELKIND_PARTITIONED_INDEX:
                               7084                 :           1020 :                 info->section = SECTION_POST_DATA;
                               7085                 :           1020 :                 break;
  162 jdavis@postgresql.or     7086                 :UBC           0 :             default:
   82 peter@eisentraut.org     7087                 :              0 :                 pg_fatal("cannot dump statistics for relation kind \"%c\"",
                               7088                 :                :                          info->relkind);
                               7089                 :                :         }
                               7090                 :                : 
  198 jdavis@postgresql.or     7091                 :CBC        3792 :         return info;
                               7092                 :                :     }
                               7093                 :            261 :     return NULL;
                               7094                 :                : }
                               7095                 :                : 
                               7096                 :                : /*
                               7097                 :                :  * getTables
                               7098                 :                :  *    read all the tables (no indexes) in the system catalogs,
                               7099                 :                :  *    and return them as an array of TableInfo structures
                               7100                 :                :  *
                               7101                 :                :  * *numTables is set to the number of tables read in
                               7102                 :                :  */
                               7103                 :                : TableInfo *
 3524 tgl@sss.pgh.pa.us        7104                 :            186 : getTables(Archive *fout, int *numTables)
                               7105                 :                : {
                               7106                 :            186 :     DumpOptions *dopt = fout->dopt;
                               7107                 :                :     PGresult   *res;
                               7108                 :                :     int         ntups;
                               7109                 :                :     int         i;
 8520                          7110                 :            186 :     PQExpBuffer query = createPQExpBuffer();
                               7111                 :                :     TableInfo  *tblinfo;
                               7112                 :                :     int         i_reltableoid;
                               7113                 :                :     int         i_reloid;
                               7114                 :                :     int         i_relname;
                               7115                 :                :     int         i_relnamespace;
                               7116                 :                :     int         i_relkind;
                               7117                 :                :     int         i_reltype;
                               7118                 :                :     int         i_relowner;
                               7119                 :                :     int         i_relchecks;
                               7120                 :                :     int         i_relhasindex;
                               7121                 :                :     int         i_relhasrules;
                               7122                 :                :     int         i_relpages;
                               7123                 :                :     int         i_reltuples;
                               7124                 :                :     int         i_relallvisible;
                               7125                 :                :     int         i_relallfrozen;
                               7126                 :                :     int         i_toastpages;
                               7127                 :                :     int         i_owning_tab;
                               7128                 :                :     int         i_owning_col;
                               7129                 :                :     int         i_reltablespace;
                               7130                 :                :     int         i_relhasoids;
                               7131                 :                :     int         i_relhastriggers;
                               7132                 :                :     int         i_relpersistence;
                               7133                 :                :     int         i_relispopulated;
                               7134                 :                :     int         i_relreplident;
                               7135                 :                :     int         i_relrowsec;
                               7136                 :                :     int         i_relforcerowsec;
                               7137                 :                :     int         i_relfrozenxid;
                               7138                 :                :     int         i_toastfrozenxid;
                               7139                 :                :     int         i_toastoid;
                               7140                 :                :     int         i_relminmxid;
                               7141                 :                :     int         i_toastminmxid;
                               7142                 :                :     int         i_reloptions;
                               7143                 :                :     int         i_checkoption;
                               7144                 :                :     int         i_toastreloptions;
                               7145                 :                :     int         i_reloftype;
                               7146                 :                :     int         i_foreignserver;
                               7147                 :                :     int         i_amname;
                               7148                 :                :     int         i_is_identity_sequence;
                               7149                 :                :     int         i_relacl;
                               7150                 :                :     int         i_acldefault;
                               7151                 :                :     int         i_ispartition;
                               7152                 :                : 
                               7153                 :                :     /*
                               7154                 :                :      * Find all the tables and table-like objects.
                               7155                 :                :      *
                               7156                 :                :      * We must fetch all tables in this phase because otherwise we cannot
                               7157                 :                :      * correctly identify inherited columns, owned sequences, etc.
                               7158                 :                :      *
                               7159                 :                :      * We include system catalogs, so that we can work if a user table is
                               7160                 :                :      * defined to inherit from a system catalog (pretty weird, but...)
                               7161                 :                :      *
                               7162                 :                :      * Note: in this phase we should collect only a minimal amount of
                               7163                 :                :      * information about each table, basically just enough to decide if it is
                               7164                 :                :      * interesting.  In particular, since we do not yet have lock on any user
                               7165                 :                :      * table, we MUST NOT invoke any server-side data collection functions
                               7166                 :                :      * (for instance, pg_get_partkeydef()).  Those are likely to fail or give
                               7167                 :                :      * wrong answers if any concurrent DDL is happening.
                               7168                 :                :      */
                               7169                 :                : 
 1096 drowley@postgresql.o     7170                 :            186 :     appendPQExpBufferStr(query,
                               7171                 :                :                          "SELECT c.tableoid, c.oid, c.relname, "
                               7172                 :                :                          "c.relnamespace, c.relkind, c.reltype, "
                               7173                 :                :                          "c.relowner, "
                               7174                 :                :                          "c.relchecks, "
                               7175                 :                :                          "c.relhasindex, c.relhasrules, c.relpages, "
                               7176                 :                :                          "c.reltuples, c.relallvisible, ");
                               7177                 :                : 
  160 jdavis@postgresql.or     7178         [ +  - ]:            186 :     if (fout->remoteVersion >= 180000)
                               7179                 :            186 :         appendPQExpBufferStr(query, "c.relallfrozen, ");
                               7180                 :                :     else
  160 jdavis@postgresql.or     7181                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS relallfrozen, ");
                               7182                 :                : 
  160 jdavis@postgresql.or     7183                 :CBC         186 :     appendPQExpBufferStr(query,
                               7184                 :                :                          "c.relhastriggers, c.relpersistence, "
                               7185                 :                :                          "c.reloftype, "
                               7186                 :                :                          "c.relacl, "
                               7187                 :                :                          "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
                               7188                 :                :                          " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
                               7189                 :                :                          "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
                               7190                 :                :                          "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
                               7191                 :                :                          "ELSE 0 END AS foreignserver, "
                               7192                 :                :                          "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
                               7193                 :                :                          "tc.oid AS toid, "
                               7194                 :                :                          "tc.relpages AS toastpages, "
                               7195                 :                :                          "tc.reloptions AS toast_reloptions, "
                               7196                 :                :                          "d.refobjid AS owning_tab, "
                               7197                 :                :                          "d.refobjsubid AS owning_col, "
                               7198                 :                :                          "tsp.spcname AS reltablespace, ");
                               7199                 :                : 
 1418 tgl@sss.pgh.pa.us        7200         [ +  - ]:            186 :     if (fout->remoteVersion >= 120000)
                               7201                 :            186 :         appendPQExpBufferStr(query,
                               7202                 :                :                              "false AS relhasoids, ");
                               7203                 :                :     else
 1418 tgl@sss.pgh.pa.us        7204                 :UBC           0 :         appendPQExpBufferStr(query,
                               7205                 :                :                              "c.relhasoids, ");
                               7206                 :                : 
 1418 tgl@sss.pgh.pa.us        7207         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90300)
                               7208                 :            186 :         appendPQExpBufferStr(query,
                               7209                 :                :                              "c.relispopulated, ");
                               7210                 :                :     else
 1418 tgl@sss.pgh.pa.us        7211                 :UBC           0 :         appendPQExpBufferStr(query,
                               7212                 :                :                              "'t' as relispopulated, ");
                               7213                 :                : 
 1418 tgl@sss.pgh.pa.us        7214         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90400)
                               7215                 :            186 :         appendPQExpBufferStr(query,
                               7216                 :                :                              "c.relreplident, ");
                               7217                 :                :     else
 1418 tgl@sss.pgh.pa.us        7218                 :UBC           0 :         appendPQExpBufferStr(query,
                               7219                 :                :                              "'d' AS relreplident, ");
                               7220                 :                : 
 1418 tgl@sss.pgh.pa.us        7221         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90500)
                               7222                 :            186 :         appendPQExpBufferStr(query,
                               7223                 :                :                              "c.relrowsecurity, c.relforcerowsecurity, ");
                               7224                 :                :     else
 1418 tgl@sss.pgh.pa.us        7225                 :UBC           0 :         appendPQExpBufferStr(query,
                               7226                 :                :                              "false AS relrowsecurity, "
                               7227                 :                :                              "false AS relforcerowsecurity, ");
                               7228                 :                : 
 1418 tgl@sss.pgh.pa.us        7229         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90300)
                               7230                 :            186 :         appendPQExpBufferStr(query,
                               7231                 :                :                              "c.relminmxid, tc.relminmxid AS tminmxid, ");
                               7232                 :                :     else
 1418 tgl@sss.pgh.pa.us        7233                 :UBC           0 :         appendPQExpBufferStr(query,
                               7234                 :                :                              "0 AS relminmxid, 0 AS tminmxid, ");
                               7235                 :                : 
 1418 tgl@sss.pgh.pa.us        7236         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90300)
                               7237                 :            186 :         appendPQExpBufferStr(query,
                               7238                 :                :                              "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
                               7239                 :                :                              "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
                               7240                 :                :                              "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
                               7241                 :                :     else
 1418 tgl@sss.pgh.pa.us        7242                 :UBC           0 :         appendPQExpBufferStr(query,
                               7243                 :                :                              "c.reloptions, NULL AS checkoption, ");
                               7244                 :                : 
 3440 sfrost@snowman.net       7245         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90600)
 1418 tgl@sss.pgh.pa.us        7246                 :            186 :         appendPQExpBufferStr(query,
                               7247                 :                :                              "am.amname, ");
                               7248                 :                :     else
 1418 tgl@sss.pgh.pa.us        7249                 :UBC           0 :         appendPQExpBufferStr(query,
                               7250                 :                :                              "NULL AS amname, ");
                               7251                 :                : 
 1418 tgl@sss.pgh.pa.us        7252         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 90600)
                               7253                 :            186 :         appendPQExpBufferStr(query,
                               7254                 :                :                              "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
                               7255                 :                :     else
 1418 tgl@sss.pgh.pa.us        7256                 :UBC           0 :         appendPQExpBufferStr(query,
                               7257                 :                :                              "false AS is_identity_sequence, ");
                               7258                 :                : 
 1418 tgl@sss.pgh.pa.us        7259         [ +  - ]:CBC         186 :     if (fout->remoteVersion >= 100000)
                               7260                 :            186 :         appendPQExpBufferStr(query,
                               7261                 :                :                              "c.relispartition AS ispartition ");
                               7262                 :                :     else
 1418 tgl@sss.pgh.pa.us        7263                 :UBC           0 :         appendPQExpBufferStr(query,
                               7264                 :                :                              "false AS ispartition ");
                               7265                 :                : 
                               7266                 :                :     /*
                               7267                 :                :      * Left join to pg_depend to pick up dependency info linking sequences to
                               7268                 :                :      * their owning column, if any (note this dependency is AUTO except for
                               7269                 :                :      * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
                               7270                 :                :      * collect the spcname.
                               7271                 :                :      */
 1418 tgl@sss.pgh.pa.us        7272                 :CBC         186 :     appendPQExpBufferStr(query,
                               7273                 :                :                          "\nFROM pg_class c\n"
                               7274                 :                :                          "LEFT JOIN pg_depend d ON "
                               7275                 :                :                          "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
                               7276                 :                :                          "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
                               7277                 :                :                          "d.objsubid = 0 AND "
                               7278                 :                :                          "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
                               7279                 :                :                          "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
                               7280                 :                : 
                               7281                 :                :     /*
                               7282                 :                :      * In 9.6 and up, left join to pg_am to pick up the amname.
                               7283                 :                :      */
                               7284         [ +  - ]:            186 :     if (fout->remoteVersion >= 90600)
                               7285                 :            186 :         appendPQExpBufferStr(query,
                               7286                 :                :                              "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
                               7287                 :                : 
                               7288                 :                :     /*
                               7289                 :                :      * We purposefully ignore toast OIDs for partitioned tables; the reason is
                               7290                 :                :      * that versions 10 and 11 have them, but later versions do not, so
                               7291                 :                :      * emitting them causes the upgrade to fail.
                               7292                 :                :      */
 1370                          7293                 :            186 :     appendPQExpBufferStr(query,
                               7294                 :                :                          "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
                               7295                 :                :                          " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
                               7296                 :                :                          " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
                               7297                 :                : 
                               7298                 :                :     /*
                               7299                 :                :      * Restrict to interesting relkinds (in particular, not indexes).  Not all
                               7300                 :                :      * relkinds are possible in older servers, but it's not worth the trouble
                               7301                 :                :      * to emit a version-dependent list.
                               7302                 :                :      *
                               7303                 :                :      * Composite-type table entries won't be dumped as such, but we have to
                               7304                 :                :      * make a DumpableObject for them so that we can track dependencies of the
                               7305                 :                :      * composite type (pg_depend entries for columns of the composite type
                               7306                 :                :      * link to the pg_class entry not the pg_type entry).
                               7307                 :                :      */
 1418                          7308                 :            186 :     appendPQExpBufferStr(query,
                               7309                 :                :                          "WHERE c.relkind IN ("
                               7310                 :                :                          CppAsString2(RELKIND_RELATION) ", "
                               7311                 :                :                          CppAsString2(RELKIND_SEQUENCE) ", "
                               7312                 :                :                          CppAsString2(RELKIND_VIEW) ", "
                               7313                 :                :                          CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
                               7314                 :                :                          CppAsString2(RELKIND_MATVIEW) ", "
                               7315                 :                :                          CppAsString2(RELKIND_FOREIGN_TABLE) ", "
                               7316                 :                :                          CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
                               7317                 :                :                          "ORDER BY c.oid");
                               7318                 :                : 
 4960 rhaas@postgresql.org     7319                 :            186 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7320                 :                : 
 8520 tgl@sss.pgh.pa.us        7321                 :            186 :     ntups = PQntuples(res);
                               7322                 :                : 
                               7323                 :            186 :     *numTables = ntups;
                               7324                 :                : 
                               7325                 :                :     /*
                               7326                 :                :      * Extract data from result and lock dumpable tables.  We do the locking
                               7327                 :                :      * before anything else, to minimize the window wherein a table could
                               7328                 :                :      * disappear under us.
                               7329                 :                :      *
                               7330                 :                :      * Note that we have to save info about all tables here, even when dumping
                               7331                 :                :      * only one, because we don't yet know which tables might be inheritance
                               7332                 :                :      * ancestors of the target table.
                               7333                 :                :      */
 4722                          7334                 :            186 :     tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
                               7335                 :                : 
 7945                          7336                 :            186 :     i_reltableoid = PQfnumber(res, "tableoid");
 8520                          7337                 :            186 :     i_reloid = PQfnumber(res, "oid");
                               7338                 :            186 :     i_relname = PQfnumber(res, "relname");
                               7339                 :            186 :     i_relnamespace = PQfnumber(res, "relnamespace");
                               7340                 :            186 :     i_relkind = PQfnumber(res, "relkind");
 1370                          7341                 :            186 :     i_reltype = PQfnumber(res, "reltype");
 1345                          7342                 :            186 :     i_relowner = PQfnumber(res, "relowner");
 8520                          7343                 :            186 :     i_relchecks = PQfnumber(res, "relchecks");
                               7344                 :            186 :     i_relhasindex = PQfnumber(res, "relhasindex");
                               7345                 :            186 :     i_relhasrules = PQfnumber(res, "relhasrules");
 1418                          7346                 :            186 :     i_relpages = PQfnumber(res, "relpages");
  193 jdavis@postgresql.or     7347                 :            186 :     i_reltuples = PQfnumber(res, "reltuples");
                               7348                 :            186 :     i_relallvisible = PQfnumber(res, "relallvisible");
  160                          7349                 :            186 :     i_relallfrozen = PQfnumber(res, "relallfrozen");
 1370 tgl@sss.pgh.pa.us        7350                 :            186 :     i_toastpages = PQfnumber(res, "toastpages");
 1418                          7351                 :            186 :     i_owning_tab = PQfnumber(res, "owning_tab");
                               7352                 :            186 :     i_owning_col = PQfnumber(res, "owning_col");
                               7353                 :            186 :     i_reltablespace = PQfnumber(res, "reltablespace");
                               7354                 :            186 :     i_relhasoids = PQfnumber(res, "relhasoids");
                               7355                 :            186 :     i_relhastriggers = PQfnumber(res, "relhastriggers");
                               7356                 :            186 :     i_relpersistence = PQfnumber(res, "relpersistence");
                               7357                 :            186 :     i_relispopulated = PQfnumber(res, "relispopulated");
                               7358                 :            186 :     i_relreplident = PQfnumber(res, "relreplident");
 4000 sfrost@snowman.net       7359                 :            186 :     i_relrowsec = PQfnumber(res, "relrowsecurity");
 3625                          7360                 :            186 :     i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
 6044 bruce@momjian.us         7361                 :            186 :     i_relfrozenxid = PQfnumber(res, "relfrozenxid");
 5265                          7362                 :            186 :     i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
 1418 tgl@sss.pgh.pa.us        7363                 :            186 :     i_toastoid = PQfnumber(res, "toid");
                               7364                 :            186 :     i_relminmxid = PQfnumber(res, "relminmxid");
 4084 bruce@momjian.us         7365                 :            186 :     i_toastminmxid = PQfnumber(res, "tminmxid");
 7006                          7366                 :            186 :     i_reloptions = PQfnumber(res, "reloptions");
 4433 sfrost@snowman.net       7367                 :            186 :     i_checkoption = PQfnumber(res, "checkoption");
 6060 alvherre@alvh.no-ip.     7368                 :            186 :     i_toastreloptions = PQfnumber(res, "toast_reloptions");
 5700 peter_e@gmx.net          7369                 :            186 :     i_reloftype = PQfnumber(res, "reloftype");
 1418 tgl@sss.pgh.pa.us        7370                 :            186 :     i_foreignserver = PQfnumber(res, "foreignserver");
                               7371                 :            186 :     i_amname = PQfnumber(res, "amname");
 3075 peter_e@gmx.net          7372                 :            186 :     i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
 1418 tgl@sss.pgh.pa.us        7373                 :            186 :     i_relacl = PQfnumber(res, "relacl");
 1370                          7374                 :            186 :     i_acldefault = PQfnumber(res, "acldefault");
 3047 sfrost@snowman.net       7375                 :            186 :     i_ispartition = PQfnumber(res, "ispartition");
                               7376                 :                : 
 3251 tgl@sss.pgh.pa.us        7377         [ +  + ]:            186 :     if (dopt->lockWaitTimeout)
                               7378                 :                :     {
                               7379                 :                :         /*
                               7380                 :                :          * Arrange to fail instead of waiting forever for a table lock.
                               7381                 :                :          *
                               7382                 :                :          * NB: this coding assumes that the only queries issued within the
                               7383                 :                :          * following loop are LOCK TABLEs; else the timeout may be undesirably
                               7384                 :                :          * applied to other things too.
                               7385                 :                :          */
 6257                          7386                 :              2 :         resetPQExpBuffer(query);
 4310 heikki.linnakangas@i     7387                 :              2 :         appendPQExpBufferStr(query, "SET statement_timeout = ");
 3980 alvherre@alvh.no-ip.     7388                 :              2 :         appendStringLiteralConn(query, dopt->lockWaitTimeout, GetConnection(fout));
 4960 rhaas@postgresql.org     7389                 :              2 :         ExecuteSqlStatement(fout, query->data);
                               7390                 :                :     }
                               7391                 :                : 
  977 tgl@sss.pgh.pa.us        7392                 :            186 :     resetPQExpBuffer(query);
                               7393                 :                : 
 8520                          7394         [ +  + ]:          49501 :     for (i = 0; i < ntups; i++)
                               7395                 :                :     {
  193 jdavis@postgresql.or     7396                 :          49315 :         int32       relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
  160                          7397                 :          49315 :         int32       relallfrozen = atoi(PQgetvalue(res, i, i_relallfrozen));
                               7398                 :                : 
 7945 tgl@sss.pgh.pa.us        7399                 :          49315 :         tblinfo[i].dobj.objType = DO_TABLE;
                               7400                 :          49315 :         tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
                               7401                 :          49315 :         tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
                               7402                 :          49315 :         AssignDumpId(&tblinfo[i].dobj);
 5034 bruce@momjian.us         7403                 :          49315 :         tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
 4961 rhaas@postgresql.org     7404                 :          98630 :         tblinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     7405                 :          49315 :             findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
 1370 tgl@sss.pgh.pa.us        7406                 :          49315 :         tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
                               7407                 :          49315 :         tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               7408                 :          49315 :         tblinfo[i].dacl.privtype = 0;
                               7409                 :          49315 :         tblinfo[i].dacl.initprivs = NULL;
 8520                          7410                 :          49315 :         tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
 1370                          7411                 :          49315 :         tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
 1345                          7412                 :          49315 :         tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
 1418                          7413                 :          49315 :         tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
 8520                          7414                 :          49315 :         tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
                               7415                 :          49315 :         tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
 4549 andrew@dunslane.net      7416                 :          49315 :         tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
 1370 tgl@sss.pgh.pa.us        7417         [ +  + ]:          49315 :         if (PQgetisnull(res, i, i_toastpages))
                               7418                 :          39514 :             tblinfo[i].toastpages = 0;
                               7419                 :                :         else
                               7420                 :           9801 :             tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
 8419                          7421         [ +  + ]:          49315 :         if (PQgetisnull(res, i, i_owning_tab))
                               7422                 :                :         {
 7945                          7423                 :          48882 :             tblinfo[i].owning_tab = InvalidOid;
 8419                          7424                 :          48882 :             tblinfo[i].owning_col = 0;
                               7425                 :                :         }
                               7426                 :                :         else
                               7427                 :                :         {
 7945                          7428                 :            433 :             tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
 8419                          7429                 :            433 :             tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
                               7430                 :                :         }
 5034 bruce@momjian.us         7431                 :          49315 :         tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
 1418 tgl@sss.pgh.pa.us        7432                 :          49315 :         tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
                               7433                 :          49315 :         tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
                               7434                 :          49315 :         tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
                               7435                 :          49315 :         tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
                               7436                 :          49315 :         tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
                               7437                 :          49315 :         tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
                               7438                 :          49315 :         tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
                               7439                 :          49315 :         tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
                               7440                 :          49315 :         tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
                               7441                 :          49315 :         tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
                               7442                 :          49315 :         tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
                               7443                 :          49315 :         tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
 5034 bruce@momjian.us         7444                 :          49315 :         tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
 1418 tgl@sss.pgh.pa.us        7445         [ +  + ]:          49315 :         if (PQgetisnull(res, i, i_checkoption))
 4433 sfrost@snowman.net       7446                 :          49263 :             tblinfo[i].checkoption = NULL;
                               7447                 :                :         else
                               7448                 :             52 :             tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
 5034 bruce@momjian.us         7449                 :          49315 :         tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
 1370 tgl@sss.pgh.pa.us        7450                 :          49315 :         tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
 1418                          7451                 :          49315 :         tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
 2376 andres@anarazel.de       7452         [ +  + ]:          49315 :         if (PQgetisnull(res, i, i_amname))
                               7453                 :          29238 :             tblinfo[i].amname = NULL;
                               7454                 :                :         else
                               7455                 :          20077 :             tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
 1418 tgl@sss.pgh.pa.us        7456                 :          49315 :         tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
                               7457                 :          49315 :         tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
                               7458                 :                : 
                               7459                 :                :         /* other fields were zeroed above */
                               7460                 :                : 
                               7461                 :                :         /*
                               7462                 :                :          * Decide whether we want to dump this table.
                               7463                 :                :          */
 7543                          7464         [ +  + ]:          49315 :         if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
 3440 sfrost@snowman.net       7465                 :            189 :             tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
                               7466                 :                :         else
                               7467                 :          49126 :             selectDumpableTable(&tblinfo[i], fout);
                               7468                 :                : 
                               7469                 :                :         /*
                               7470                 :                :          * Now, consider the table "interesting" if we need to dump its
                               7471                 :                :          * definition, data or its statistics.  Later on, we'll skip a lot of
                               7472                 :                :          * data collection for uninteresting tables.
                               7473                 :                :          *
                               7474                 :                :          * Note: the "interesting" flag will also be set by flagInhTables for
                               7475                 :                :          * parents of interesting tables, so that we collect necessary
                               7476                 :                :          * inheritance info even when the parents are not themselves being
                               7477                 :                :          * dumped.  This is the main reason why we need an "interesting" flag
                               7478                 :                :          * that's separate from the components-to-dump bitmask.
                               7479                 :                :          */
 1370 tgl@sss.pgh.pa.us        7480                 :          49315 :         tblinfo[i].interesting = (tblinfo[i].dobj.dump &
                               7481                 :                :                                   (DUMP_COMPONENT_DEFINITION |
                               7482                 :                :                                    DUMP_COMPONENT_DATA |
  198 jdavis@postgresql.or     7483                 :          49315 :                                    DUMP_COMPONENT_STATISTICS)) != 0;
                               7484                 :                : 
 1418 tgl@sss.pgh.pa.us        7485                 :          49315 :         tblinfo[i].dummy_view = false;  /* might get set during sort */
                               7486                 :          49315 :         tblinfo[i].postponed_def = false;   /* might get set during sort */
                               7487                 :                : 
                               7488                 :                :         /* Tables have data */
 1370                          7489                 :          49315 :         tblinfo[i].dobj.components |= DUMP_COMPONENT_DATA;
                               7490                 :                : 
                               7491                 :                :         /* Mark whether table has an ACL */
                               7492         [ +  + ]:          49315 :         if (!PQgetisnull(res, i, i_relacl))
                               7493                 :          39106 :             tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               7494                 :          49315 :         tblinfo[i].hascolumnACLs = false;   /* may get set later */
                               7495                 :                : 
                               7496                 :                :         /* Add statistics */
  198 jdavis@postgresql.or     7497         [ +  + ]:          49315 :         if (tblinfo[i].interesting)
                               7498                 :                :         {
                               7499                 :                :             RelStatsInfo *stats;
                               7500                 :                : 
  162                          7501                 :          14784 :             stats = getRelationStatistics(fout, &tblinfo[i].dobj,
                               7502                 :           7392 :                                           tblinfo[i].relpages,
                               7503                 :                :                                           PQgetvalue(res, i, i_reltuples),
                               7504                 :                :                                           relallvisible, relallfrozen,
                               7505                 :           7392 :                                           tblinfo[i].relkind, NULL, 0);
                               7506         [ +  + ]:           7392 :             if (tblinfo[i].relkind == RELKIND_MATVIEW)
                               7507                 :            490 :                 tblinfo[i].stats = stats;
                               7508                 :                :         }
                               7509                 :                : 
                               7510                 :                :         /*
                               7511                 :                :          * Read-lock target tables to make sure they aren't DROPPED or altered
                               7512                 :                :          * in schema before we get around to dumping them.
                               7513                 :                :          *
                               7514                 :                :          * Note that we don't explicitly lock parents of the target tables; we
                               7515                 :                :          * assume our lock on the child is enough to prevent schema
                               7516                 :                :          * alterations to parent tables.
                               7517                 :                :          *
                               7518                 :                :          * NOTE: it'd be kinda nice to lock other relations too, not only
                               7519                 :                :          * plain or partitioned tables, but the backend doesn't presently
                               7520                 :                :          * allow that.
                               7521                 :                :          *
                               7522                 :                :          * We only need to lock the table for certain components; see
                               7523                 :                :          * pg_dump.h
                               7524                 :                :          */
 1370 tgl@sss.pgh.pa.us        7525         [ +  + ]:          49315 :         if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
 1765                          7526         [ +  + ]:           7392 :             (tblinfo[i].relkind == RELKIND_RELATION ||
 1370                          7527         [ +  + ]:           2112 :              tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
                               7528                 :                :         {
                               7529                 :                :             /*
                               7530                 :                :              * Tables are locked in batches.  When dumping from a remote
                               7531                 :                :              * server this can save a significant amount of time by reducing
                               7532                 :                :              * the number of round trips.
                               7533                 :                :              */
  977                          7534         [ +  + ]:           5898 :             if (query->len == 0)
                               7535                 :            122 :                 appendPQExpBuffer(query, "LOCK TABLE %s",
                               7536                 :            122 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7537                 :                :             else
                               7538                 :                :             {
                               7539                 :           5776 :                 appendPQExpBuffer(query, ", %s",
                               7540                 :           5776 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7541                 :                : 
                               7542                 :                :                 /* Arbitrarily end a batch when query length reaches 100K. */
                               7543         [ -  + ]:           5776 :                 if (query->len >= 100000)
                               7544                 :                :                 {
                               7545                 :                :                     /* Lock another batch of tables. */
  977 tgl@sss.pgh.pa.us        7546                 :UBC           0 :                     appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7547                 :              0 :                     ExecuteSqlStatement(fout, query->data);
                               7548                 :              0 :                     resetPQExpBuffer(query);
                               7549                 :                :                 }
                               7550                 :                :             }
                               7551                 :                :         }
                               7552                 :                :     }
                               7553                 :                : 
  977 tgl@sss.pgh.pa.us        7554         [ +  + ]:CBC         186 :     if (query->len != 0)
                               7555                 :                :     {
                               7556                 :                :         /* Lock the tables in the last batch. */
                               7557                 :            122 :         appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7558                 :            122 :         ExecuteSqlStatement(fout, query->data);
                               7559                 :                :     }
                               7560                 :                : 
 3251                          7561         [ +  + ]:            185 :     if (dopt->lockWaitTimeout)
                               7562                 :                :     {
 4960 rhaas@postgresql.org     7563                 :              2 :         ExecuteSqlStatement(fout, "SET statement_timeout = 0");
                               7564                 :                :     }
                               7565                 :                : 
 8520 tgl@sss.pgh.pa.us        7566                 :            185 :     PQclear(res);
                               7567                 :                : 
 4907                          7568                 :            185 :     destroyPQExpBuffer(query);
                               7569                 :                : 
                               7570                 :            185 :     return tblinfo;
                               7571                 :                : }
                               7572                 :                : 
                               7573                 :                : /*
                               7574                 :                :  * getOwnedSeqs
                               7575                 :                :  *    identify owned sequences and mark them as dumpable if owning table is
                               7576                 :                :  *
                               7577                 :                :  * We used to do this in getTables(), but it's better to do it after the
                               7578                 :                :  * index used by findTableByOid() has been set up.
                               7579                 :                :  */
                               7580                 :                : void
                               7581                 :            185 : getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
                               7582                 :                : {
                               7583                 :                :     int         i;
                               7584                 :                : 
                               7585                 :                :     /*
                               7586                 :                :      * Force sequences that are "owned" by table columns to be dumped whenever
                               7587                 :                :      * their owning table is being dumped.
                               7588                 :                :      */
                               7589         [ +  + ]:          49228 :     for (i = 0; i < numTables; i++)
                               7590                 :                :     {
 6956                          7591                 :          49043 :         TableInfo  *seqinfo = &tblinfo[i];
                               7592                 :                :         TableInfo  *owning_tab;
                               7593                 :                : 
                               7594         [ +  + ]:          49043 :         if (!OidIsValid(seqinfo->owning_tab))
                               7595                 :          48613 :             continue;           /* not an owned sequence */
                               7596                 :                : 
 4907                          7597                 :            430 :         owning_tab = findTableByOid(seqinfo->owning_tab);
 3165 sfrost@snowman.net       7598         [ -  + ]:            430 :         if (owning_tab == NULL)
 1247 tgl@sss.pgh.pa.us        7599                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                               7600                 :                :                      seqinfo->owning_tab, seqinfo->dobj.catId.oid);
                               7601                 :                : 
                               7602                 :                :         /*
                               7603                 :                :          * For an identity sequence, dump exactly the same components for the
                               7604                 :                :          * sequence as for the owning table.  This is important because we
                               7605                 :                :          * treat the identity sequence as an integral part of the table.  For
                               7606                 :                :          * example, there is not any DDL command that allows creation of such
                               7607                 :                :          * a sequence independently of the table.
                               7608                 :                :          *
                               7609                 :                :          * For other owned sequences such as serial sequences, we need to dump
                               7610                 :                :          * the components that are being dumped for the table and any
                               7611                 :                :          * components that the sequence is explicitly marked with.
                               7612                 :                :          *
                               7613                 :                :          * We can't simply use the set of components which are being dumped
                               7614                 :                :          * for the table as the table might be in an extension (and only the
                               7615                 :                :          * non-extension components, eg: ACLs if changed, security labels, and
                               7616                 :                :          * policies, are being dumped) while the sequence is not (and
                               7617                 :                :          * therefore the definition and other components should also be
                               7618                 :                :          * dumped).
                               7619                 :                :          *
                               7620                 :                :          * If the sequence is part of the extension then it should be properly
                               7621                 :                :          * marked by checkExtensionMembership() and this will be a no-op as
                               7622                 :                :          * the table will be equivalently marked.
                               7623                 :                :          */
  267 tgl@sss.pgh.pa.us        7624         [ +  + ]:CBC         430 :         if (seqinfo->is_identity_sequence)
                               7625                 :            205 :             seqinfo->dobj.dump = owning_tab->dobj.dump;
                               7626                 :                :         else
                               7627                 :            225 :             seqinfo->dobj.dump |= owning_tab->dobj.dump;
                               7628                 :                : 
                               7629                 :                :         /* Make sure that necessary data is available if we're dumping it */
 3324 sfrost@snowman.net       7630         [ +  + ]:            430 :         if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
                               7631                 :                :         {
 4907 tgl@sss.pgh.pa.us        7632                 :            334 :             seqinfo->interesting = true;
  267                          7633                 :            334 :             owning_tab->interesting = true;
                               7634                 :                :         }
                               7635                 :                :     }
10651 scrappy@hub.org          7636                 :            185 : }
                               7637                 :                : 
                               7638                 :                : /*
                               7639                 :                :  * getInherits
                               7640                 :                :  *    read all the inheritance information
                               7641                 :                :  * from the system catalogs return them in the InhInfo* structure
                               7642                 :                :  *
                               7643                 :                :  * numInherits is set to the number of pairs read in
                               7644                 :                :  */
                               7645                 :                : InhInfo *
 4961 rhaas@postgresql.org     7646                 :            185 : getInherits(Archive *fout, int *numInherits)
                               7647                 :                : {
                               7648                 :                :     PGresult   *res;
                               7649                 :                :     int         ntups;
                               7650                 :                :     int         i;
 9278 bruce@momjian.us         7651                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               7652                 :                :     InhInfo    *inhinfo;
                               7653                 :                : 
                               7654                 :                :     int         i_inhrelid;
                               7655                 :                :     int         i_inhparent;
                               7656                 :                : 
                               7657                 :                :     /* find all the inheritance information */
 3047 sfrost@snowman.net       7658                 :            185 :     appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
                               7659                 :                : 
 4960 rhaas@postgresql.org     7660                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7661                 :                : 
10226 bruce@momjian.us         7662                 :            185 :     ntups = PQntuples(res);
                               7663                 :                : 
                               7664                 :            185 :     *numInherits = ntups;
                               7665                 :                : 
 5034                          7666                 :            185 :     inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
                               7667                 :                : 
 9420                          7668                 :            185 :     i_inhrelid = PQfnumber(res, "inhrelid");
10226                          7669                 :            185 :     i_inhparent = PQfnumber(res, "inhparent");
                               7670                 :                : 
                               7671         [ +  + ]:           3690 :     for (i = 0; i < ntups; i++)
                               7672                 :                :     {
 7945 tgl@sss.pgh.pa.us        7673                 :           3505 :         inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
                               7674                 :           3505 :         inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
                               7675                 :                :     }
                               7676                 :                : 
10226 bruce@momjian.us         7677                 :            185 :     PQclear(res);
                               7678                 :                : 
 8800 tgl@sss.pgh.pa.us        7679                 :            185 :     destroyPQExpBuffer(query);
                               7680                 :                : 
10226 bruce@momjian.us         7681                 :            185 :     return inhinfo;
                               7682                 :                : }
                               7683                 :                : 
                               7684                 :                : /*
                               7685                 :                :  * getPartitioningInfo
                               7686                 :                :  *    get information about partitioning
                               7687                 :                :  *
                               7688                 :                :  * For the most part, we only collect partitioning info about tables we
                               7689                 :                :  * intend to dump.  However, this function has to consider all partitioned
                               7690                 :                :  * tables in the database, because we need to know about parents of partitions
                               7691                 :                :  * we are going to dump even if the parents themselves won't be dumped.
                               7692                 :                :  *
                               7693                 :                :  * Specifically, what we need to know is whether each partitioned table
                               7694                 :                :  * has an "unsafe" partitioning scheme that requires us to force
                               7695                 :                :  * load-via-partition-root mode for its children.  Currently the only case
                               7696                 :                :  * for which we force that is hash partitioning on enum columns, since the
                               7697                 :                :  * hash codes depend on enum value OIDs which won't be replicated across
                               7698                 :                :  * dump-and-reload.  There are other cases in which load-via-partition-root
                               7699                 :                :  * might be necessary, but we expect users to cope with them.
                               7700                 :                :  */
                               7701                 :                : void
  904 tgl@sss.pgh.pa.us        7702                 :            185 : getPartitioningInfo(Archive *fout)
                               7703                 :                : {
                               7704                 :                :     PQExpBuffer query;
                               7705                 :                :     PGresult   *res;
                               7706                 :                :     int         ntups;
                               7707                 :                : 
                               7708                 :                :     /* hash partitioning didn't exist before v11 */
                               7709         [ -  + ]:            185 :     if (fout->remoteVersion < 110000)
  904 tgl@sss.pgh.pa.us        7710                 :UBC           0 :         return;
                               7711                 :                :     /* needn't bother if not dumping data */
  285 nathan@postgresql.or     7712         [ +  + ]:CBC         185 :     if (!fout->dopt->dumpData)
  904 tgl@sss.pgh.pa.us        7713                 :             40 :         return;
                               7714                 :                : 
                               7715                 :            145 :     query = createPQExpBuffer();
                               7716                 :                : 
                               7717                 :                :     /*
                               7718                 :                :      * Unsafe partitioning schemes are exactly those for which hash enum_ops
                               7719                 :                :      * appears among the partition opclasses.  We needn't check partstrat.
                               7720                 :                :      *
                               7721                 :                :      * Note that this query may well retrieve info about tables we aren't
                               7722                 :                :      * going to dump and hence have no lock on.  That's okay since we need not
                               7723                 :                :      * invoke any unsafe server-side functions.
                               7724                 :                :      */
                               7725                 :            145 :     appendPQExpBufferStr(query,
                               7726                 :                :                          "SELECT partrelid FROM pg_partitioned_table WHERE\n"
                               7727                 :                :                          "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
                               7728                 :                :                          "ON c.opcmethod = a.oid\n"
                               7729                 :                :                          "WHERE opcname = 'enum_ops' "
                               7730                 :                :                          "AND opcnamespace = 'pg_catalog'::regnamespace "
                               7731                 :                :                          "AND amname = 'hash') = ANY(partclass)");
                               7732                 :                : 
                               7733                 :            145 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7734                 :                : 
                               7735                 :            145 :     ntups = PQntuples(res);
                               7736                 :                : 
                               7737         [ +  + ]:            194 :     for (int i = 0; i < ntups; i++)
                               7738                 :                :     {
                               7739                 :             49 :         Oid         tabrelid = atooid(PQgetvalue(res, i, 0));
                               7740                 :                :         TableInfo  *tbinfo;
                               7741                 :                : 
                               7742                 :             49 :         tbinfo = findTableByOid(tabrelid);
                               7743         [ -  + ]:             49 :         if (tbinfo == NULL)
  904 tgl@sss.pgh.pa.us        7744                 :UBC           0 :             pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
                               7745                 :                :                      tabrelid);
  904 tgl@sss.pgh.pa.us        7746                 :CBC          49 :         tbinfo->unsafe_partitions = true;
                               7747                 :                :     }
                               7748                 :                : 
                               7749                 :            145 :     PQclear(res);
                               7750                 :                : 
                               7751                 :            145 :     destroyPQExpBuffer(query);
                               7752                 :                : }
                               7753                 :                : 
                               7754                 :                : /*
                               7755                 :                :  * getIndexes
                               7756                 :                :  *    get information about every index on a dumpable table
                               7757                 :                :  *
                               7758                 :                :  * Note: index data is not returned directly to the caller, but it
                               7759                 :                :  * does get entered into the DumpableObject tables.
                               7760                 :                :  */
                               7761                 :                : void
 4961 rhaas@postgresql.org     7762                 :            185 : getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                               7763                 :                : {
 7945 tgl@sss.pgh.pa.us        7764                 :            185 :     PQExpBuffer query = createPQExpBuffer();
 1370                          7765                 :            185 :     PQExpBuffer tbloids = createPQExpBuffer();
                               7766                 :                :     PGresult   *res;
                               7767                 :                :     int         ntups;
                               7768                 :                :     int         curtblindx;
                               7769                 :                :     IndxInfo   *indxinfo;
                               7770                 :                :     int         i_tableoid,
                               7771                 :                :                 i_oid,
                               7772                 :                :                 i_indrelid,
                               7773                 :                :                 i_indexname,
                               7774                 :                :                 i_relpages,
                               7775                 :                :                 i_reltuples,
                               7776                 :                :                 i_relallvisible,
                               7777                 :                :                 i_relallfrozen,
                               7778                 :                :                 i_parentidx,
                               7779                 :                :                 i_indexdef,
                               7780                 :                :                 i_indnkeyatts,
                               7781                 :                :                 i_indnatts,
                               7782                 :                :                 i_indkey,
                               7783                 :                :                 i_indisclustered,
                               7784                 :                :                 i_indisreplident,
                               7785                 :                :                 i_indnullsnotdistinct,
                               7786                 :                :                 i_contype,
                               7787                 :                :                 i_conname,
                               7788                 :                :                 i_condeferrable,
                               7789                 :                :                 i_condeferred,
                               7790                 :                :                 i_conperiod,
                               7791                 :                :                 i_contableoid,
                               7792                 :                :                 i_conoid,
                               7793                 :                :                 i_condef,
                               7794                 :                :                 i_indattnames,
                               7795                 :                :                 i_tablespace,
                               7796                 :                :                 i_indreloptions,
                               7797                 :                :                 i_indstatcols,
                               7798                 :                :                 i_indstatvals;
                               7799                 :                : 
                               7800                 :                :     /*
                               7801                 :                :      * We want to perform just one query against pg_index.  However, we
                               7802                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               7803                 :                :      * the client side, because some of the server-side functions we need
                               7804                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               7805                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               7806                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               7807                 :                :      */
                               7808                 :            185 :     appendPQExpBufferChar(tbloids, '{');
                               7809         [ +  + ]:          49228 :     for (int i = 0; i < numTables; i++)
                               7810                 :                :     {
 7945                          7811                 :          49043 :         TableInfo  *tbinfo = &tblinfo[i];
                               7812                 :                : 
 4570 kgrittn@postgresql.o     7813         [ +  + ]:          49043 :         if (!tbinfo->hasindex)
 7945 tgl@sss.pgh.pa.us        7814                 :          34745 :             continue;
                               7815                 :                : 
                               7816                 :                :         /*
                               7817                 :                :          * We can ignore indexes of uninteresting tables.
                               7818                 :                :          */
 1370                          7819         [ +  + ]:          14298 :         if (!tbinfo->interesting)
 7945                          7820                 :          12225 :             continue;
                               7821                 :                : 
                               7822                 :                :         /* OK, we need info for this table */
 1370                          7823         [ +  + ]:           2073 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               7824                 :           1989 :             appendPQExpBufferChar(tbloids, ',');
                               7825                 :           2073 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               7826                 :                :     }
                               7827                 :            185 :     appendPQExpBufferChar(tbloids, '}');
                               7828                 :                : 
 1096 drowley@postgresql.o     7829                 :            185 :     appendPQExpBufferStr(query,
                               7830                 :                :                          "SELECT t.tableoid, t.oid, i.indrelid, "
                               7831                 :                :                          "t.relname AS indexname, "
                               7832                 :                :                          "t.relpages, t.reltuples, t.relallvisible, ");
                               7833                 :                : 
  160 jdavis@postgresql.or     7834         [ +  - ]:            185 :     if (fout->remoteVersion >= 180000)
                               7835                 :            185 :         appendPQExpBufferStr(query, "t.relallfrozen, ");
                               7836                 :                :     else
  160 jdavis@postgresql.or     7837                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS relallfrozen, ");
                               7838                 :                : 
  160 jdavis@postgresql.or     7839                 :CBC         185 :     appendPQExpBufferStr(query,
                               7840                 :                :                          "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                               7841                 :                :                          "i.indkey, i.indisclustered, "
                               7842                 :                :                          "c.contype, c.conname, "
                               7843                 :                :                          "c.condeferrable, c.condeferred, "
                               7844                 :                :                          "c.tableoid AS contableoid, "
                               7845                 :                :                          "c.oid AS conoid, "
                               7846                 :                :                          "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
                               7847                 :                :                          "CASE WHEN i.indexprs IS NOT NULL THEN "
                               7848                 :                :                          "(SELECT pg_catalog.array_agg(attname ORDER BY attnum)"
                               7849                 :                :                          "  FROM pg_catalog.pg_attribute "
                               7850                 :                :                          "  WHERE attrelid = i.indexrelid) "
                               7851                 :                :                          "ELSE NULL END AS indattnames, "
                               7852                 :                :                          "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
                               7853                 :                :                          "t.reloptions AS indreloptions, ");
                               7854                 :                : 
                               7855                 :                : 
 1356 peter@eisentraut.org     7856         [ +  - ]:            185 :     if (fout->remoteVersion >= 90400)
 1096 drowley@postgresql.o     7857                 :            185 :         appendPQExpBufferStr(query,
                               7858                 :                :                              "i.indisreplident, ");
                               7859                 :                :     else
 1096 drowley@postgresql.o     7860                 :UBC           0 :         appendPQExpBufferStr(query,
                               7861                 :                :                              "false AS indisreplident, ");
                               7862                 :                : 
 1356 peter@eisentraut.org     7863         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 110000)
 1096 drowley@postgresql.o     7864                 :            185 :         appendPQExpBufferStr(query,
                               7865                 :                :                              "inh.inhparent AS parentidx, "
                               7866                 :                :                              "i.indnkeyatts AS indnkeyatts, "
                               7867                 :                :                              "i.indnatts AS indnatts, "
                               7868                 :                :                              "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
                               7869                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7870                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7871                 :                :                              "    attstattarget >= 0) AS indstatcols, "
                               7872                 :                :                              "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
                               7873                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7874                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7875                 :                :                              "    attstattarget >= 0) AS indstatvals, ");
                               7876                 :                :     else
 1096 drowley@postgresql.o     7877                 :UBC           0 :         appendPQExpBufferStr(query,
                               7878                 :                :                              "0 AS parentidx, "
                               7879                 :                :                              "i.indnatts AS indnkeyatts, "
                               7880                 :                :                              "i.indnatts AS indnatts, "
                               7881                 :                :                              "'' AS indstatcols, "
                               7882                 :                :                              "'' AS indstatvals, ");
                               7883                 :                : 
 1311 peter@eisentraut.org     7884         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 150000)
 1096 drowley@postgresql.o     7885                 :            185 :         appendPQExpBufferStr(query,
                               7886                 :                :                              "i.indnullsnotdistinct, ");
                               7887                 :                :     else
 1096 drowley@postgresql.o     7888                 :UBC           0 :         appendPQExpBufferStr(query,
                               7889                 :                :                              "false AS indnullsnotdistinct, ");
                               7890                 :                : 
  354 peter@eisentraut.org     7891         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 180000)
                               7892                 :            185 :         appendPQExpBufferStr(query,
                               7893                 :                :                              "c.conperiod ");
                               7894                 :                :     else
  354 peter@eisentraut.org     7895                 :UBC           0 :         appendPQExpBufferStr(query,
                               7896                 :                :                              "NULL AS conperiod ");
                               7897                 :                : 
                               7898                 :                :     /*
                               7899                 :                :      * The point of the messy-looking outer join is to find a constraint that
                               7900                 :                :      * is related by an internal dependency link to the index. If we find one,
                               7901                 :                :      * create a CONSTRAINT entry linked to the INDEX entry.  We assume an
                               7902                 :                :      * index won't have more than one internal dependency.
                               7903                 :                :      *
                               7904                 :                :      * Note: the check on conrelid is redundant, but useful because that
                               7905                 :                :      * column is indexed while conindid is not.
                               7906                 :                :      */
 1370 tgl@sss.pgh.pa.us        7907         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 110000)
                               7908                 :                :     {
                               7909                 :            185 :         appendPQExpBuffer(query,
                               7910                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7911                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               7912                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               7913                 :                :                           "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
                               7914                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               7915                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               7916                 :                :                           "i.indexrelid = c.conindid AND "
                               7917                 :                :                           "c.contype IN ('p','u','x')) "
                               7918                 :                :                           "LEFT JOIN pg_catalog.pg_inherits inh "
                               7919                 :                :                           "ON (inh.inhrelid = indexrelid) "
                               7920                 :                :                           "WHERE (i.indisvalid OR t2.relkind = 'p') "
                               7921                 :                :                           "AND i.indisready "
                               7922                 :                :                           "ORDER BY i.indrelid, indexname",
                               7923                 :                :                           tbloids->data);
                               7924                 :                :     }
                               7925                 :                :     else
                               7926                 :                :     {
                               7927                 :                :         /*
                               7928                 :                :          * the test on indisready is necessary in 9.2, and harmless in
                               7929                 :                :          * earlier/later versions
                               7930                 :                :          */
 1370 tgl@sss.pgh.pa.us        7931                 :UBC           0 :         appendPQExpBuffer(query,
                               7932                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7933                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               7934                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               7935                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               7936                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               7937                 :                :                           "i.indexrelid = c.conindid AND "
                               7938                 :                :                           "c.contype IN ('p','u','x')) "
                               7939                 :                :                           "WHERE i.indisvalid AND i.indisready "
                               7940                 :                :                           "ORDER BY i.indrelid, indexname",
                               7941                 :                :                           tbloids->data);
                               7942                 :                :     }
                               7943                 :                : 
 1370 tgl@sss.pgh.pa.us        7944                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7945                 :                : 
                               7946                 :            185 :     ntups = PQntuples(res);
                               7947                 :                : 
                               7948                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               7949                 :            185 :     i_oid = PQfnumber(res, "oid");
                               7950                 :            185 :     i_indrelid = PQfnumber(res, "indrelid");
                               7951                 :            185 :     i_indexname = PQfnumber(res, "indexname");
  193 jdavis@postgresql.or     7952                 :            185 :     i_relpages = PQfnumber(res, "relpages");
                               7953                 :            185 :     i_reltuples = PQfnumber(res, "reltuples");
                               7954                 :            185 :     i_relallvisible = PQfnumber(res, "relallvisible");
  160                          7955                 :            185 :     i_relallfrozen = PQfnumber(res, "relallfrozen");
 1370 tgl@sss.pgh.pa.us        7956                 :            185 :     i_parentidx = PQfnumber(res, "parentidx");
                               7957                 :            185 :     i_indexdef = PQfnumber(res, "indexdef");
                               7958                 :            185 :     i_indnkeyatts = PQfnumber(res, "indnkeyatts");
                               7959                 :            185 :     i_indnatts = PQfnumber(res, "indnatts");
                               7960                 :            185 :     i_indkey = PQfnumber(res, "indkey");
                               7961                 :            185 :     i_indisclustered = PQfnumber(res, "indisclustered");
                               7962                 :            185 :     i_indisreplident = PQfnumber(res, "indisreplident");
 1311 peter@eisentraut.org     7963                 :            185 :     i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
 1370 tgl@sss.pgh.pa.us        7964                 :            185 :     i_contype = PQfnumber(res, "contype");
                               7965                 :            185 :     i_conname = PQfnumber(res, "conname");
                               7966                 :            185 :     i_condeferrable = PQfnumber(res, "condeferrable");
                               7967                 :            185 :     i_condeferred = PQfnumber(res, "condeferred");
  354 peter@eisentraut.org     7968                 :            185 :     i_conperiod = PQfnumber(res, "conperiod");
 1370 tgl@sss.pgh.pa.us        7969                 :            185 :     i_contableoid = PQfnumber(res, "contableoid");
                               7970                 :            185 :     i_conoid = PQfnumber(res, "conoid");
                               7971                 :            185 :     i_condef = PQfnumber(res, "condef");
  192                          7972                 :            185 :     i_indattnames = PQfnumber(res, "indattnames");
 1370                          7973                 :            185 :     i_tablespace = PQfnumber(res, "tablespace");
                               7974                 :            185 :     i_indreloptions = PQfnumber(res, "indreloptions");
                               7975                 :            185 :     i_indstatcols = PQfnumber(res, "indstatcols");
                               7976                 :            185 :     i_indstatvals = PQfnumber(res, "indstatvals");
                               7977                 :                : 
                               7978                 :            185 :     indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
                               7979                 :                : 
                               7980                 :                :     /*
                               7981                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               7982                 :                :      * j is handled by the inner loop.
                               7983                 :                :      */
                               7984                 :            185 :     curtblindx = -1;
                               7985         [ +  + ]:           2240 :     for (int j = 0; j < ntups;)
                               7986                 :                :     {
                               7987                 :           2055 :         Oid         indrelid = atooid(PQgetvalue(res, j, i_indrelid));
                               7988                 :           2055 :         TableInfo  *tbinfo = NULL;
  192                          7989                 :           2055 :         char      **indAttNames = NULL;
                               7990                 :           2055 :         int         nindAttNames = 0;
                               7991                 :                :         int         numinds;
                               7992                 :                : 
                               7993                 :                :         /* Count rows for this table */
 1370                          7994         [ +  + ]:           2697 :         for (numinds = 1; numinds < ntups - j; numinds++)
                               7995         [ +  + ]:           2613 :             if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
                               7996                 :           1971 :                 break;
                               7997                 :                : 
                               7998                 :                :         /*
                               7999                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8000                 :                :          * order.
                               8001                 :                :          */
                               8002         [ +  - ]:          24779 :         while (++curtblindx < numTables)
                               8003                 :                :         {
                               8004                 :          24779 :             tbinfo = &tblinfo[curtblindx];
                               8005         [ +  + ]:          24779 :             if (tbinfo->dobj.catId.oid == indrelid)
                               8006                 :           2055 :                 break;
                               8007                 :                :         }
                               8008         [ -  + ]:           2055 :         if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        8009                 :UBC           0 :             pg_fatal("unrecognized table OID %u", indrelid);
                               8010                 :                :         /* cross-check that we only got requested tables */
 1370 tgl@sss.pgh.pa.us        8011         [ +  - ]:CBC        2055 :         if (!tbinfo->hasindex ||
                               8012         [ -  + ]:           2055 :             !tbinfo->interesting)
 1247 tgl@sss.pgh.pa.us        8013                 :UBC           0 :             pg_fatal("unexpected index data for table \"%s\"",
                               8014                 :                :                      tbinfo->dobj.name);
                               8015                 :                : 
                               8016                 :                :         /* Save data for this table */
 1370 tgl@sss.pgh.pa.us        8017                 :CBC        2055 :         tbinfo->indexes = indxinfo + j;
                               8018                 :           2055 :         tbinfo->numIndexes = numinds;
                               8019                 :                : 
                               8020         [ +  + ]:           4752 :         for (int c = 0; c < numinds; c++, j++)
                               8021                 :                :         {
                               8022                 :                :             char        contype;
                               8023                 :                :             char        indexkind;
                               8024                 :                :             RelStatsInfo *relstats;
  193 jdavis@postgresql.or     8025                 :           2697 :             int32       relpages = atoi(PQgetvalue(res, j, i_relpages));
                               8026                 :           2697 :             int32       relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
  160                          8027                 :           2697 :             int32       relallfrozen = atoi(PQgetvalue(res, j, i_relallfrozen));
                               8028                 :                : 
 7945 tgl@sss.pgh.pa.us        8029                 :           2697 :             indxinfo[j].dobj.objType = DO_INDEX;
                               8030                 :           2697 :             indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               8031                 :           2697 :             indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               8032                 :           2697 :             AssignDumpId(&indxinfo[j].dobj);
 2787 alvherre@alvh.no-ip.     8033                 :           2697 :             indxinfo[j].dobj.dump = tbinfo->dobj.dump;
 5034 bruce@momjian.us         8034                 :           2697 :             indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
 7857 tgl@sss.pgh.pa.us        8035                 :           2697 :             indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7945                          8036                 :           2697 :             indxinfo[j].indextable = tbinfo;
 5034 bruce@momjian.us         8037                 :           2697 :             indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 2699 heikki.linnakangas@i     8038                 :           2697 :             indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
 2709 teodor@sigaev.ru         8039                 :           2697 :             indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
 5034 bruce@momjian.us         8040                 :           2697 :             indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
 3535 tgl@sss.pgh.pa.us        8041                 :           2697 :             indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
 2454 michael@paquier.xyz      8042                 :           2697 :             indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
                               8043                 :           2697 :             indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
 2709 teodor@sigaev.ru         8044                 :           2697 :             indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
 7945 tgl@sss.pgh.pa.us        8045                 :           2697 :             parseOidArray(PQgetvalue(res, j, i_indkey),
 2709 teodor@sigaev.ru         8046                 :           2697 :                           indxinfo[j].indkeys, indxinfo[j].indnattrs);
 7945 tgl@sss.pgh.pa.us        8047                 :           2697 :             indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
 4320 rhaas@postgresql.org     8048                 :           2697 :             indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
 1311 peter@eisentraut.org     8049                 :           2697 :             indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
 2787 alvherre@alvh.no-ip.     8050                 :           2697 :             indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
 1941 tgl@sss.pgh.pa.us        8051                 :           2697 :             indxinfo[j].partattaches = (SimplePtrList)
                               8052                 :                :             {
                               8053                 :                :                 NULL, NULL
                               8054                 :                :             };
                               8055                 :                : 
  198 jdavis@postgresql.or     8056         [ +  + ]:           2697 :             if (indxinfo[j].parentidx == 0)
                               8057                 :           2085 :                 indexkind = RELKIND_INDEX;
                               8058                 :                :             else
                               8059                 :            612 :                 indexkind = RELKIND_PARTITIONED_INDEX;
                               8060                 :                : 
  192 tgl@sss.pgh.pa.us        8061         [ +  + ]:           2697 :             if (!PQgetisnull(res, j, i_indattnames))
                               8062                 :                :             {
                               8063         [ -  + ]:            158 :                 if (!parsePGArray(PQgetvalue(res, j, i_indattnames),
                               8064                 :                :                                   &indAttNames, &nindAttNames))
  192 tgl@sss.pgh.pa.us        8065                 :UBC           0 :                     pg_fatal("could not parse %s array", "indattnames");
                               8066                 :                :             }
                               8067                 :                : 
  193 jdavis@postgresql.or     8068                 :CBC        2697 :             relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
                               8069                 :                :                                              PQgetvalue(res, j, i_reltuples),
                               8070                 :                :                                              relallvisible, relallfrozen, indexkind,
                               8071                 :                :                                              indAttNames, nindAttNames);
                               8072                 :                : 
  192 tgl@sss.pgh.pa.us        8073                 :           2697 :             contype = *(PQgetvalue(res, j, i_contype));
 5752                          8074   [ +  +  +  +  :           2697 :             if (contype == 'p' || contype == 'u' || contype == 'x')
                                              +  + ]
 7945                          8075                 :           1573 :             {
                               8076                 :                :                 /*
                               8077                 :                :                  * If we found a constraint matching the index, create an
                               8078                 :                :                  * entry for it.
                               8079                 :                :                  */
                               8080                 :                :                 ConstraintInfo *constrinfo;
                               8081                 :                : 
 1413                          8082                 :           1573 :                 constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
                               8083                 :           1573 :                 constrinfo->dobj.objType = DO_CONSTRAINT;
                               8084                 :           1573 :                 constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               8085                 :           1573 :                 constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               8086                 :           1573 :                 AssignDumpId(&constrinfo->dobj);
                               8087                 :           1573 :                 constrinfo->dobj.dump = tbinfo->dobj.dump;
                               8088                 :           1573 :                 constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               8089                 :           1573 :                 constrinfo->dobj.namespace = tbinfo->dobj.namespace;
                               8090                 :           1573 :                 constrinfo->contable = tbinfo;
                               8091                 :           1573 :                 constrinfo->condomain = NULL;
                               8092                 :           1573 :                 constrinfo->contype = contype;
 5752                          8093         [ +  + ]:           1573 :                 if (contype == 'x')
 1413                          8094                 :             10 :                     constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               8095                 :                :                 else
                               8096                 :           1563 :                     constrinfo->condef = NULL;
                               8097                 :           1573 :                 constrinfo->confrelid = InvalidOid;
                               8098                 :           1573 :                 constrinfo->conindex = indxinfo[j].dobj.dumpId;
                               8099                 :           1573 :                 constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
                               8100                 :           1573 :                 constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
  354 peter@eisentraut.org     8101                 :           1573 :                 constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
 1413 tgl@sss.pgh.pa.us        8102                 :           1573 :                 constrinfo->conislocal = true;
                               8103                 :           1573 :                 constrinfo->separate = true;
                               8104                 :                : 
                               8105                 :           1573 :                 indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
  198 jdavis@postgresql.or     8106         [ +  + ]:           1573 :                 if (relstats != NULL)
                               8107                 :            598 :                     addObjectDependency(&relstats->dobj, constrinfo->dobj.dumpId);
                               8108                 :                :             }
                               8109                 :                :             else
                               8110                 :                :             {
                               8111                 :                :                 /* Plain secondary index */
 7945 tgl@sss.pgh.pa.us        8112                 :           1124 :                 indxinfo[j].indexconstraint = 0;
                               8113                 :                :             }
                               8114                 :                :         }
                               8115                 :                :     }
                               8116                 :                : 
 1370                          8117                 :            185 :     PQclear(res);
                               8118                 :                : 
 7945                          8119                 :            185 :     destroyPQExpBuffer(query);
 1370                          8120                 :            185 :     destroyPQExpBuffer(tbloids);
 7945                          8121                 :            185 : }
                               8122                 :                : 
                               8123                 :                : /*
                               8124                 :                :  * getExtendedStatistics
                               8125                 :                :  *    get information about extended-statistics objects.
                               8126                 :                :  *
                               8127                 :                :  * Note: extended statistics data is not returned directly to the caller, but
                               8128                 :                :  * it does get entered into the DumpableObject tables.
                               8129                 :                :  */
                               8130                 :                : void
 2764                          8131                 :            185 : getExtendedStatistics(Archive *fout)
                               8132                 :                : {
                               8133                 :                :     PQExpBuffer query;
                               8134                 :                :     PGresult   *res;
                               8135                 :                :     StatsExtInfo *statsextinfo;
                               8136                 :                :     int         ntups;
                               8137                 :                :     int         i_tableoid;
                               8138                 :                :     int         i_oid;
                               8139                 :                :     int         i_stxname;
                               8140                 :                :     int         i_stxnamespace;
                               8141                 :                :     int         i_stxowner;
                               8142                 :                :     int         i_stxrelid;
                               8143                 :                :     int         i_stattarget;
                               8144                 :                :     int         i;
                               8145                 :                : 
                               8146                 :                :     /* Extended statistics were new in v10 */
 3088 alvherre@alvh.no-ip.     8147         [ -  + ]:            185 :     if (fout->remoteVersion < 100000)
 3088 alvherre@alvh.no-ip.     8148                 :UBC           0 :         return;
                               8149                 :                : 
 3088 alvherre@alvh.no-ip.     8150                 :CBC         185 :     query = createPQExpBuffer();
                               8151                 :                : 
 2188 tomas.vondra@postgre     8152         [ -  + ]:            185 :     if (fout->remoteVersion < 130000)
 1096 drowley@postgresql.o     8153                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               8154                 :                :                              "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
                               8155                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               8156                 :                :     else
 1096 drowley@postgresql.o     8157                 :CBC         185 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               8158                 :                :                              "stxnamespace, stxowner, stxrelid, stxstattarget "
                               8159                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               8160                 :                : 
 2764 tgl@sss.pgh.pa.us        8161                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8162                 :                : 
                               8163                 :            185 :     ntups = PQntuples(res);
                               8164                 :                : 
                               8165                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               8166                 :            185 :     i_oid = PQfnumber(res, "oid");
                               8167                 :            185 :     i_stxname = PQfnumber(res, "stxname");
                               8168                 :            185 :     i_stxnamespace = PQfnumber(res, "stxnamespace");
 1345                          8169                 :            185 :     i_stxowner = PQfnumber(res, "stxowner");
  617                          8170                 :            185 :     i_stxrelid = PQfnumber(res, "stxrelid");
 2188 tomas.vondra@postgre     8171                 :            185 :     i_stattarget = PQfnumber(res, "stxstattarget");
                               8172                 :                : 
 2764 tgl@sss.pgh.pa.us        8173                 :            185 :     statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
                               8174                 :                : 
                               8175         [ +  + ]:            366 :     for (i = 0; i < ntups; i++)
                               8176                 :                :     {
                               8177                 :            181 :         statsextinfo[i].dobj.objType = DO_STATSEXT;
                               8178                 :            181 :         statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8179                 :            181 :         statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8180                 :            181 :         AssignDumpId(&statsextinfo[i].dobj);
                               8181                 :            181 :         statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
                               8182                 :            362 :         statsextinfo[i].dobj.namespace =
 1838 peter@eisentraut.org     8183                 :            181 :             findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
 1345 tgl@sss.pgh.pa.us        8184                 :            181 :         statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
  617                          8185                 :            362 :         statsextinfo[i].stattable =
                               8186                 :            181 :             findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
  538 peter@eisentraut.org     8187         [ +  + ]:            181 :         if (PQgetisnull(res, i, i_stattarget))
                               8188                 :            130 :             statsextinfo[i].stattarget = -1;
                               8189                 :                :         else
                               8190                 :             51 :             statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
                               8191                 :                : 
                               8192                 :                :         /* Decide whether we want to dump it */
  617 tgl@sss.pgh.pa.us        8193                 :            181 :         selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
                               8194                 :                :     }
                               8195                 :                : 
 2764                          8196                 :            185 :     PQclear(res);
 3088 alvherre@alvh.no-ip.     8197                 :            185 :     destroyPQExpBuffer(query);
                               8198                 :                : }
                               8199                 :                : 
                               8200                 :                : /*
                               8201                 :                :  * getConstraints
                               8202                 :                :  *
                               8203                 :                :  * Get info about constraints on dumpable tables.
                               8204                 :                :  *
                               8205                 :                :  * Currently handles foreign keys only.
                               8206                 :                :  * Unique and primary key constraints are handled with indexes,
                               8207                 :                :  * while check constraints are processed in getTableAttrs().
                               8208                 :                :  */
                               8209                 :                : void
 4961 rhaas@postgresql.org     8210                 :            185 : getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
                               8211                 :                : {
 1370 tgl@sss.pgh.pa.us        8212                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               8213                 :            185 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8214                 :                :     PGresult   *res;
                               8215                 :                :     int         ntups;
                               8216                 :                :     int         curtblindx;
                               8217                 :            185 :     TableInfo  *tbinfo = NULL;
                               8218                 :                :     ConstraintInfo *constrinfo;
                               8219                 :                :     int         i_contableoid,
                               8220                 :                :                 i_conoid,
                               8221                 :                :                 i_conrelid,
                               8222                 :                :                 i_conname,
                               8223                 :                :                 i_confrelid,
                               8224                 :                :                 i_conindid,
                               8225                 :                :                 i_condef;
                               8226                 :                : 
                               8227                 :                :     /*
                               8228                 :                :      * We want to perform just one query against pg_constraint.  However, we
                               8229                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               8230                 :                :      * the client side, because some of the server-side functions we need
                               8231                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8232                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8233                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8234                 :                :      */
                               8235                 :            185 :     appendPQExpBufferChar(tbloids, '{');
                               8236         [ +  + ]:          49228 :     for (int i = 0; i < numTables; i++)
                               8237                 :                :     {
 1113 drowley@postgresql.o     8238                 :          49043 :         TableInfo  *tinfo = &tblinfo[i];
                               8239                 :                : 
  157 peter@eisentraut.org     8240         [ +  + ]:          49043 :         if (!(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7945 tgl@sss.pgh.pa.us        8241                 :          41705 :             continue;
                               8242                 :                : 
                               8243                 :                :         /* OK, we need info for this table */
 1370                          8244         [ +  + ]:           7338 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8245                 :           7215 :             appendPQExpBufferChar(tbloids, ',');
 1113 drowley@postgresql.o     8246                 :           7338 :         appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
                               8247                 :                :     }
 1370 tgl@sss.pgh.pa.us        8248                 :            185 :     appendPQExpBufferChar(tbloids, '}');
                               8249                 :                : 
                               8250                 :            185 :     appendPQExpBufferStr(query,
                               8251                 :                :                          "SELECT c.tableoid, c.oid, "
                               8252                 :                :                          "conrelid, conname, confrelid, ");
                               8253         [ +  - ]:            185 :     if (fout->remoteVersion >= 110000)
                               8254                 :            185 :         appendPQExpBufferStr(query, "conindid, ");
                               8255                 :                :     else
 1370 tgl@sss.pgh.pa.us        8256                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS conindid, ");
 1370 tgl@sss.pgh.pa.us        8257                 :CBC         185 :     appendPQExpBuffer(query,
                               8258                 :                :                       "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
                               8259                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8260                 :                :                       "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               8261                 :                :                       "WHERE contype = 'f' ",
                               8262                 :                :                       tbloids->data);
                               8263         [ +  - ]:            185 :     if (fout->remoteVersion >= 110000)
                               8264                 :            185 :         appendPQExpBufferStr(query,
                               8265                 :                :                              "AND conparentid = 0 ");
                               8266                 :            185 :     appendPQExpBufferStr(query,
                               8267                 :                :                          "ORDER BY conrelid, conname");
                               8268                 :                : 
                               8269                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8270                 :                : 
                               8271                 :            185 :     ntups = PQntuples(res);
                               8272                 :                : 
                               8273                 :            185 :     i_contableoid = PQfnumber(res, "tableoid");
                               8274                 :            185 :     i_conoid = PQfnumber(res, "oid");
                               8275                 :            185 :     i_conrelid = PQfnumber(res, "conrelid");
                               8276                 :            185 :     i_conname = PQfnumber(res, "conname");
                               8277                 :            185 :     i_confrelid = PQfnumber(res, "confrelid");
                               8278                 :            185 :     i_conindid = PQfnumber(res, "conindid");
                               8279                 :            185 :     i_condef = PQfnumber(res, "condef");
                               8280                 :                : 
                               8281                 :            185 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
                               8282                 :                : 
                               8283                 :            185 :     curtblindx = -1;
                               8284         [ +  + ]:            368 :     for (int j = 0; j < ntups; j++)
                               8285                 :                :     {
                               8286                 :            183 :         Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               8287                 :                :         TableInfo  *reftable;
                               8288                 :                : 
                               8289                 :                :         /*
                               8290                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8291                 :                :          * order.
                               8292                 :                :          */
                               8293   [ +  +  +  + ]:            183 :         if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
                               8294                 :                :         {
                               8295         [ +  - ]:          15008 :             while (++curtblindx < numTables)
                               8296                 :                :             {
                               8297                 :          15008 :                 tbinfo = &tblinfo[curtblindx];
                               8298         [ +  + ]:          15008 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               8299                 :            173 :                     break;
                               8300                 :                :             }
                               8301         [ -  + ]:            173 :             if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        8302                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               8303                 :                :         }
                               8304                 :                : 
 1370 tgl@sss.pgh.pa.us        8305                 :CBC         183 :         constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
                               8306                 :            183 :         constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               8307                 :            183 :         constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               8308                 :            183 :         AssignDumpId(&constrinfo[j].dobj);
                               8309                 :            183 :         constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               8310                 :            183 :         constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               8311                 :            183 :         constrinfo[j].contable = tbinfo;
                               8312                 :            183 :         constrinfo[j].condomain = NULL;
                               8313                 :            183 :         constrinfo[j].contype = 'f';
                               8314                 :            183 :         constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               8315                 :            183 :         constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
                               8316                 :            183 :         constrinfo[j].conindex = 0;
                               8317                 :            183 :         constrinfo[j].condeferrable = false;
                               8318                 :            183 :         constrinfo[j].condeferred = false;
                               8319                 :            183 :         constrinfo[j].conislocal = true;
                               8320                 :            183 :         constrinfo[j].separate = true;
                               8321                 :                : 
                               8322                 :                :         /*
                               8323                 :                :          * Restoring an FK that points to a partitioned table requires that
                               8324                 :                :          * all partition indexes have been attached beforehand. Ensure that
                               8325                 :                :          * happens by making the constraint depend on each index partition
                               8326                 :                :          * attach object.
                               8327                 :                :          */
                               8328                 :            183 :         reftable = findTableByOid(constrinfo[j].confrelid);
                               8329   [ +  -  +  + ]:            183 :         if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
                               8330                 :                :         {
                               8331                 :             20 :             Oid         indexOid = atooid(PQgetvalue(res, j, i_conindid));
                               8332                 :                : 
                               8333         [ +  - ]:             20 :             if (indexOid != InvalidOid)
                               8334                 :                :             {
                               8335         [ +  - ]:             20 :                 for (int k = 0; k < reftable->numIndexes; k++)
                               8336                 :                :                 {
                               8337                 :                :                     IndxInfo   *refidx;
                               8338                 :                : 
                               8339                 :                :                     /* not our index? */
                               8340         [ -  + ]:             20 :                     if (reftable->indexes[k].dobj.catId.oid != indexOid)
 1370 tgl@sss.pgh.pa.us        8341                 :UBC           0 :                         continue;
                               8342                 :                : 
 1370 tgl@sss.pgh.pa.us        8343                 :CBC          20 :                     refidx = &reftable->indexes[k];
                               8344                 :             20 :                     addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
                               8345                 :             20 :                     break;
                               8346                 :                :                 }
                               8347                 :                :             }
                               8348                 :                :         }
                               8349                 :                :     }
                               8350                 :                : 
                               8351                 :            185 :     PQclear(res);
                               8352                 :                : 
 7945                          8353                 :            185 :     destroyPQExpBuffer(query);
 1370                          8354                 :            185 :     destroyPQExpBuffer(tbloids);
 7945                          8355                 :            185 : }
                               8356                 :                : 
                               8357                 :                : /*
                               8358                 :                :  * addConstrChildIdxDeps
                               8359                 :                :  *
                               8360                 :                :  * Recursive subroutine for getConstraints
                               8361                 :                :  *
                               8362                 :                :  * Given an object representing a foreign key constraint and an index on the
                               8363                 :                :  * partitioned table it references, mark the constraint object as dependent
                               8364                 :                :  * on the DO_INDEX_ATTACH object of each index partition, recursively
                               8365                 :                :  * drilling down to their partitions if any.  This ensures that the FK is not
                               8366                 :                :  * restored until the index is fully marked valid.
                               8367                 :                :  */
                               8368                 :                : static void
 1669 peter@eisentraut.org     8369                 :             45 : addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
                               8370                 :                : {
                               8371                 :                :     SimplePtrListCell *cell;
                               8372                 :                : 
 1849 alvherre@alvh.no-ip.     8373         [ -  + ]:             45 :     Assert(dobj->objType == DO_FK_CONSTRAINT);
                               8374                 :                : 
                               8375         [ +  + ]:            155 :     for (cell = refidx->partattaches.head; cell; cell = cell->next)
                               8376                 :                :     {
                               8377                 :            110 :         IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
                               8378                 :                : 
                               8379                 :            110 :         addObjectDependency(dobj, attach->dobj.dumpId);
                               8380                 :                : 
                               8381         [ +  + ]:            110 :         if (attach->partitionIdx->partattaches.head != NULL)
                               8382                 :             25 :             addConstrChildIdxDeps(dobj, attach->partitionIdx);
                               8383                 :                :     }
                               8384                 :             45 : }
                               8385                 :                : 
                               8386                 :                : /*
                               8387                 :                :  * getDomainConstraints
                               8388                 :                :  *
                               8389                 :                :  * Get info about constraints on a domain.
                               8390                 :                :  */
                               8391                 :                : static void
 4961 rhaas@postgresql.org     8392                 :            164 : getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
                               8393                 :                : {
                               8394                 :                :     ConstraintInfo *constrinfo;
 1370 tgl@sss.pgh.pa.us        8395                 :            164 :     PQExpBuffer query = createPQExpBuffer();
                               8396                 :                :     PGresult   *res;
                               8397                 :                :     int         i_tableoid,
                               8398                 :                :                 i_oid,
                               8399                 :                :                 i_conname,
                               8400                 :                :                 i_consrc,
                               8401                 :                :                 i_convalidated,
                               8402                 :                :                 i_contype;
                               8403                 :                :     int         ntups;
                               8404                 :                : 
                               8405         [ +  + ]:            164 :     if (!fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS])
                               8406                 :                :     {
                               8407                 :                :         /*
                               8408                 :                :          * Set up query for constraint-specific details.  For servers 17 and
                               8409                 :                :          * up, domains have constraints of type 'n' as well as 'c', otherwise
                               8410                 :                :          * just the latter.
                               8411                 :                :          */
   47 alvherre@kurilemu.de     8412                 :             49 :         appendPQExpBuffer(query,
                               8413                 :                :                           "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
                               8414                 :                :                           "SELECT tableoid, oid, conname, "
                               8415                 :                :                           "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
                               8416                 :                :                           "convalidated, contype "
                               8417                 :                :                           "FROM pg_catalog.pg_constraint "
                               8418                 :                :                           "WHERE contypid = $1 AND contype IN (%s) "
                               8419                 :                :                           "ORDER BY conname",
                               8420         [ -  + ]:             49 :                           fout->remoteVersion < 170000 ? "'c'" : "'c', 'n'");
                               8421                 :                : 
 1370 tgl@sss.pgh.pa.us        8422                 :             49 :         ExecuteSqlStatement(fout, query->data);
                               8423                 :                : 
                               8424                 :             49 :         fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS] = true;
                               8425                 :                :     }
                               8426                 :                : 
                               8427                 :            164 :     printfPQExpBuffer(query,
                               8428                 :                :                       "EXECUTE getDomainConstraints('%u')",
                               8429                 :                :                       tyinfo->dobj.catId.oid);
                               8430                 :                : 
 4960 rhaas@postgresql.org     8431                 :            164 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8432                 :                : 
 7945 tgl@sss.pgh.pa.us        8433                 :            164 :     ntups = PQntuples(res);
                               8434                 :                : 
                               8435                 :            164 :     i_tableoid = PQfnumber(res, "tableoid");
                               8436                 :            164 :     i_oid = PQfnumber(res, "oid");
                               8437                 :            164 :     i_conname = PQfnumber(res, "conname");
                               8438                 :            164 :     i_consrc = PQfnumber(res, "consrc");
   47 alvherre@kurilemu.de     8439                 :            164 :     i_convalidated = PQfnumber(res, "convalidated");
                               8440                 :            164 :     i_contype = PQfnumber(res, "contype");
                               8441                 :                : 
 5034 bruce@momjian.us         8442                 :            164 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
 5736                          8443                 :            164 :     tyinfo->domChecks = constrinfo;
                               8444                 :                : 
                               8445                 :                :     /* 'i' tracks result rows; 'j' counts CHECK constraints */
   47 alvherre@kurilemu.de     8446         [ +  + ]:            342 :     for (int i = 0, j = 0; i < ntups; i++)
                               8447                 :                :     {
                               8448                 :            178 :         bool        validated = PQgetvalue(res, i, i_convalidated)[0] == 't';
                               8449                 :            178 :         char        contype = (PQgetvalue(res, i, i_contype))[0];
                               8450                 :                :         ConstraintInfo *constraint;
                               8451                 :                : 
                               8452         [ +  + ]:            178 :         if (contype == CONSTRAINT_CHECK)
                               8453                 :                :         {
                               8454                 :            119 :             constraint = &constrinfo[j++];
                               8455                 :            119 :             tyinfo->nDomChecks++;
                               8456                 :                :         }
                               8457                 :                :         else
                               8458                 :                :         {
                               8459         [ -  + ]:             59 :             Assert(contype == CONSTRAINT_NOTNULL);
                               8460         [ -  + ]:             59 :             Assert(tyinfo->notnull == NULL);
                               8461                 :                :             /* use last item in array for the not-null constraint */
                               8462                 :             59 :             tyinfo->notnull = &(constrinfo[ntups - 1]);
                               8463                 :             59 :             constraint = tyinfo->notnull;
                               8464                 :                :         }
                               8465                 :                : 
                               8466                 :            178 :         constraint->dobj.objType = DO_CONSTRAINT;
                               8467                 :            178 :         constraint->dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8468                 :            178 :         constraint->dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8469                 :            178 :         AssignDumpId(&(constraint->dobj));
                               8470                 :            178 :         constraint->dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
                               8471                 :            178 :         constraint->dobj.namespace = tyinfo->dobj.namespace;
                               8472                 :            178 :         constraint->contable = NULL;
                               8473                 :            178 :         constraint->condomain = tyinfo;
                               8474                 :            178 :         constraint->contype = contype;
                               8475                 :            178 :         constraint->condef = pg_strdup(PQgetvalue(res, i, i_consrc));
                               8476                 :            178 :         constraint->confrelid = InvalidOid;
                               8477                 :            178 :         constraint->conindex = 0;
                               8478                 :            178 :         constraint->condeferrable = false;
                               8479                 :            178 :         constraint->condeferred = false;
                               8480                 :            178 :         constraint->conislocal = true;
                               8481                 :                : 
                               8482                 :            178 :         constraint->separate = !validated;
                               8483                 :                : 
                               8484                 :                :         /*
                               8485                 :                :          * Make the domain depend on the constraint, ensuring it won't be
                               8486                 :                :          * output till any constraint dependencies are OK.  If the constraint
                               8487                 :                :          * has not been validated, it's going to be dumped after the domain
                               8488                 :                :          * anyway, so this doesn't matter.
                               8489                 :                :          */
 5034 alvherre@alvh.no-ip.     8490         [ +  + ]:            178 :         if (validated)
   47 alvherre@kurilemu.de     8491                 :            173 :             addObjectDependency(&tyinfo->dobj, constraint->dobj.dumpId);
                               8492                 :                :     }
                               8493                 :                : 
 7945 tgl@sss.pgh.pa.us        8494                 :            164 :     PQclear(res);
                               8495                 :                : 
                               8496                 :            164 :     destroyPQExpBuffer(query);
                               8497                 :            164 : }
                               8498                 :                : 
                               8499                 :                : /*
                               8500                 :                :  * getRules
                               8501                 :                :  *    get basic information about every rule in the system
                               8502                 :                :  */
                               8503                 :                : void
  431 nathan@postgresql.or     8504                 :            185 : getRules(Archive *fout)
                               8505                 :                : {
                               8506                 :                :     PGresult   *res;
                               8507                 :                :     int         ntups;
                               8508                 :                :     int         i;
 7945 tgl@sss.pgh.pa.us        8509                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               8510                 :                :     RuleInfo   *ruleinfo;
                               8511                 :                :     int         i_tableoid;
                               8512                 :                :     int         i_oid;
                               8513                 :                :     int         i_rulename;
                               8514                 :                :     int         i_ruletable;
                               8515                 :                :     int         i_ev_type;
                               8516                 :                :     int         i_is_instead;
                               8517                 :                :     int         i_ev_enabled;
                               8518                 :                : 
 1362                          8519                 :            185 :     appendPQExpBufferStr(query, "SELECT "
                               8520                 :                :                          "tableoid, oid, rulename, "
                               8521                 :                :                          "ev_class AS ruletable, ev_type, is_instead, "
                               8522                 :                :                          "ev_enabled "
                               8523                 :                :                          "FROM pg_rewrite "
                               8524                 :                :                          "ORDER BY oid");
                               8525                 :                : 
 4960 rhaas@postgresql.org     8526                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8527                 :                : 
 7945 tgl@sss.pgh.pa.us        8528                 :            185 :     ntups = PQntuples(res);
                               8529                 :                : 
 5034 bruce@momjian.us         8530                 :            185 :     ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
                               8531                 :                : 
 7945 tgl@sss.pgh.pa.us        8532                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               8533                 :            185 :     i_oid = PQfnumber(res, "oid");
                               8534                 :            185 :     i_rulename = PQfnumber(res, "rulename");
                               8535                 :            185 :     i_ruletable = PQfnumber(res, "ruletable");
                               8536                 :            185 :     i_ev_type = PQfnumber(res, "ev_type");
                               8537                 :            185 :     i_is_instead = PQfnumber(res, "is_instead");
 6746 JanWieck@Yahoo.com       8538                 :            185 :     i_ev_enabled = PQfnumber(res, "ev_enabled");
                               8539                 :                : 
 7945 tgl@sss.pgh.pa.us        8540         [ +  + ]:          28812 :     for (i = 0; i < ntups; i++)
                               8541                 :                :     {
                               8542                 :                :         Oid         ruletableoid;
                               8543                 :                : 
                               8544                 :          28627 :         ruleinfo[i].dobj.objType = DO_RULE;
                               8545                 :          28627 :         ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8546                 :          28627 :         ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8547                 :          28627 :         AssignDumpId(&ruleinfo[i].dobj);
 5034 bruce@momjian.us         8548                 :          28627 :         ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
 7945 tgl@sss.pgh.pa.us        8549                 :          28627 :         ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                               8550                 :          28627 :         ruleinfo[i].ruletable = findTableByOid(ruletableoid);
 7481                          8551         [ -  + ]:          28627 :         if (ruleinfo[i].ruletable == NULL)
 1247 tgl@sss.pgh.pa.us        8552                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
                               8553                 :                :                      ruletableoid, ruleinfo[i].dobj.catId.oid);
 7857 tgl@sss.pgh.pa.us        8554                 :CBC       28627 :         ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
 7128                          8555                 :          28627 :         ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
 7945                          8556                 :          28627 :         ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
                               8557                 :          28627 :         ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
 6746 JanWieck@Yahoo.com       8558                 :          28627 :         ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
 7945 tgl@sss.pgh.pa.us        8559         [ +  - ]:          28627 :         if (ruleinfo[i].ruletable)
                               8560                 :                :         {
                               8561                 :                :             /*
                               8562                 :                :              * If the table is a view or materialized view, force its ON
                               8563                 :                :              * SELECT rule to be sorted before the view itself --- this
                               8564                 :                :              * ensures that any dependencies for the rule affect the table's
                               8565                 :                :              * positioning. Other rules are forced to appear after their
                               8566                 :                :              * table.
                               8567                 :                :              */
 4570 kgrittn@postgresql.o     8568         [ +  + ]:          28627 :             if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
 4549 andrew@dunslane.net      8569         [ +  + ]:            797 :                  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
 7945 tgl@sss.pgh.pa.us        8570   [ +  +  +  - ]:          28396 :                 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
                               8571                 :                :             {
                               8572                 :          27984 :                 addObjectDependency(&ruleinfo[i].ruletable->dobj,
                               8573                 :          27984 :                                     ruleinfo[i].dobj.dumpId);
                               8574                 :                :                 /* We'll merge the rule into CREATE VIEW, if possible */
 7571                          8575                 :          27984 :                 ruleinfo[i].separate = false;
                               8576                 :                :             }
                               8577                 :                :             else
                               8578                 :                :             {
 7945                          8579                 :            643 :                 addObjectDependency(&ruleinfo[i].dobj,
                               8580                 :            643 :                                     ruleinfo[i].ruletable->dobj.dumpId);
 7571                          8581                 :            643 :                 ruleinfo[i].separate = true;
                               8582                 :                :             }
                               8583                 :                :         }
                               8584                 :                :         else
 7571 tgl@sss.pgh.pa.us        8585                 :UBC           0 :             ruleinfo[i].separate = true;
                               8586                 :                :     }
                               8587                 :                : 
 7945 tgl@sss.pgh.pa.us        8588                 :CBC         185 :     PQclear(res);
                               8589                 :                : 
                               8590                 :            185 :     destroyPQExpBuffer(query);
                               8591                 :            185 : }
                               8592                 :                : 
                               8593                 :                : /*
                               8594                 :                :  * getTriggers
                               8595                 :                :  *    get information about every trigger on a dumpable table
                               8596                 :                :  *
                               8597                 :                :  * Note: trigger data is not returned directly to the caller, but it
                               8598                 :                :  * does get entered into the DumpableObject tables.
                               8599                 :                :  */
                               8600                 :                : void
 4961 rhaas@postgresql.org     8601                 :            185 : getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                               8602                 :                : {
 7945 tgl@sss.pgh.pa.us        8603                 :            185 :     PQExpBuffer query = createPQExpBuffer();
 1370                          8604                 :            185 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8605                 :                :     PGresult   *res;
                               8606                 :                :     int         ntups;
                               8607                 :                :     int         curtblindx;
                               8608                 :                :     TriggerInfo *tginfo;
                               8609                 :                :     int         i_tableoid,
                               8610                 :                :                 i_oid,
                               8611                 :                :                 i_tgrelid,
                               8612                 :                :                 i_tgname,
                               8613                 :                :                 i_tgenabled,
                               8614                 :                :                 i_tgispartition,
                               8615                 :                :                 i_tgdef;
                               8616                 :                : 
                               8617                 :                :     /*
                               8618                 :                :      * We want to perform just one query against pg_trigger.  However, we
                               8619                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               8620                 :                :      * the client side, because some of the server-side functions we need
                               8621                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8622                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8623                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8624                 :                :      */
                               8625                 :            185 :     appendPQExpBufferChar(tbloids, '{');
                               8626         [ +  + ]:          49228 :     for (int i = 0; i < numTables; i++)
                               8627                 :                :     {
 7945                          8628                 :          49043 :         TableInfo  *tbinfo = &tblinfo[i];
                               8629                 :                : 
 3440 sfrost@snowman.net       8630         [ +  + ]:          49043 :         if (!tbinfo->hastriggers ||
                               8631         [ +  + ]:           1168 :             !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7945 tgl@sss.pgh.pa.us        8632                 :          48137 :             continue;
                               8633                 :                : 
                               8634                 :                :         /* OK, we need info for this table */
 1370                          8635         [ +  + ]:            906 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8636                 :            849 :             appendPQExpBufferChar(tbloids, ',');
                               8637                 :            906 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               8638                 :                :     }
                               8639                 :            185 :     appendPQExpBufferChar(tbloids, '}');
                               8640                 :                : 
 1340 alvherre@alvh.no-ip.     8641         [ +  - ]:            185 :     if (fout->remoteVersion >= 150000)
                               8642                 :                :     {
                               8643                 :                :         /*
                               8644                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8645                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8646                 :                :          * under-parenthesization.
                               8647                 :                :          *
                               8648                 :                :          * NB: We need to see partition triggers in case the tgenabled flag
                               8649                 :                :          * has been changed from the parent.
                               8650                 :                :          */
                               8651                 :            185 :         appendPQExpBuffer(query,
                               8652                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8653                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8654                 :                :                           "t.tgenabled, t.tableoid, t.oid, "
                               8655                 :                :                           "t.tgparentid <> 0 AS tgispartition\n"
                               8656                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8657                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8658                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8659                 :                :                           "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
                               8660                 :                :                           "OR t.tgenabled != u.tgenabled) "
                               8661                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8662                 :                :                           tbloids->data);
                               8663                 :                :     }
 1340 alvherre@alvh.no-ip.     8664         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 130000)
                               8665                 :                :     {
                               8666                 :                :         /*
                               8667                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8668                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8669                 :                :          * under-parenthesization.
                               8670                 :                :          *
                               8671                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8672                 :                :          * tgenabled flag has been changed from the parent.
                               8673                 :                :          */
 1370 tgl@sss.pgh.pa.us        8674                 :              0 :         appendPQExpBuffer(query,
                               8675                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8676                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8677                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
                               8678                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8679                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8680                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8681                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
                               8682                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8683                 :                :                           tbloids->data);
                               8684                 :                :     }
                               8685         [ #  # ]:              0 :     else if (fout->remoteVersion >= 110000)
                               8686                 :                :     {
                               8687                 :                :         /*
                               8688                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8689                 :                :          * tgenabled flag has been changed from the parent. No tgparentid in
                               8690                 :                :          * version 11-12, so we have to match them via pg_depend.
                               8691                 :                :          *
                               8692                 :                :          * See above about pretty=true in pg_get_triggerdef.
                               8693                 :                :          */
                               8694                 :              0 :         appendPQExpBuffer(query,
                               8695                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8696                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8697                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
                               8698                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8699                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8700                 :                :                           "LEFT JOIN pg_catalog.pg_depend AS d ON "
                               8701                 :                :                           " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8702                 :                :                           " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8703                 :                :                           " d.objid = t.oid "
                               8704                 :                :                           "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
                               8705                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
                               8706                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8707                 :                :                           tbloids->data);
                               8708                 :                :     }
                               8709                 :                :     else
                               8710                 :                :     {
                               8711                 :                :         /* See above about pretty=true in pg_get_triggerdef */
                               8712                 :              0 :         appendPQExpBuffer(query,
                               8713                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8714                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8715                 :                :                           "t.tgenabled, false as tgispartition, "
                               8716                 :                :                           "t.tableoid, t.oid "
                               8717                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8718                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8719                 :                :                           "WHERE NOT tgisinternal "
                               8720                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8721                 :                :                           tbloids->data);
                               8722                 :                :     }
                               8723                 :                : 
 1370 tgl@sss.pgh.pa.us        8724                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8725                 :                : 
                               8726                 :            185 :     ntups = PQntuples(res);
                               8727                 :                : 
                               8728                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               8729                 :            185 :     i_oid = PQfnumber(res, "oid");
                               8730                 :            185 :     i_tgrelid = PQfnumber(res, "tgrelid");
                               8731                 :            185 :     i_tgname = PQfnumber(res, "tgname");
                               8732                 :            185 :     i_tgenabled = PQfnumber(res, "tgenabled");
 1340 alvherre@alvh.no-ip.     8733                 :            185 :     i_tgispartition = PQfnumber(res, "tgispartition");
 1370 tgl@sss.pgh.pa.us        8734                 :            185 :     i_tgdef = PQfnumber(res, "tgdef");
                               8735                 :                : 
                               8736                 :            185 :     tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
                               8737                 :                : 
                               8738                 :                :     /*
                               8739                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               8740                 :                :      * j is handled by the inner loop.
                               8741                 :                :      */
                               8742                 :            185 :     curtblindx = -1;
                               8743         [ +  + ]:            521 :     for (int j = 0; j < ntups;)
                               8744                 :                :     {
                               8745                 :            336 :         Oid         tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
                               8746                 :            336 :         TableInfo  *tbinfo = NULL;
                               8747                 :                :         int         numtrigs;
                               8748                 :                : 
                               8749                 :                :         /* Count rows for this table */
                               8750         [ +  + ]:            553 :         for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
                               8751         [ +  + ]:            496 :             if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
                               8752                 :            279 :                 break;
                               8753                 :                : 
                               8754                 :                :         /*
                               8755                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8756                 :                :          * order.
                               8757                 :                :          */
                               8758         [ +  - ]:          17616 :         while (++curtblindx < numTables)
                               8759                 :                :         {
                               8760                 :          17616 :             tbinfo = &tblinfo[curtblindx];
                               8761         [ +  + ]:          17616 :             if (tbinfo->dobj.catId.oid == tgrelid)
                               8762                 :            336 :                 break;
                               8763                 :                :         }
                               8764         [ -  + ]:            336 :         if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        8765                 :UBC           0 :             pg_fatal("unrecognized table OID %u", tgrelid);
                               8766                 :                : 
                               8767                 :                :         /* Save data for this table */
 1370 tgl@sss.pgh.pa.us        8768                 :CBC         336 :         tbinfo->triggers = tginfo + j;
                               8769                 :            336 :         tbinfo->numTriggers = numtrigs;
                               8770                 :                : 
                               8771         [ +  + ]:            889 :         for (int c = 0; c < numtrigs; c++, j++)
                               8772                 :                :         {
 7945                          8773                 :            553 :             tginfo[j].dobj.objType = DO_TRIGGER;
                               8774                 :            553 :             tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               8775                 :            553 :             tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               8776                 :            553 :             AssignDumpId(&tginfo[j].dobj);
 5034 bruce@momjian.us         8777                 :            553 :             tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
 7857 tgl@sss.pgh.pa.us        8778                 :            553 :             tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7945                          8779                 :            553 :             tginfo[j].tgtable = tbinfo;
 6746 JanWieck@Yahoo.com       8780                 :            553 :             tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
 1340 alvherre@alvh.no-ip.     8781                 :            553 :             tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
  601 peter@eisentraut.org     8782                 :            553 :             tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
                               8783                 :                :         }
                               8784                 :                :     }
                               8785                 :                : 
 1370 tgl@sss.pgh.pa.us        8786                 :            185 :     PQclear(res);
                               8787                 :                : 
 7945                          8788                 :            185 :     destroyPQExpBuffer(query);
 1370                          8789                 :            185 :     destroyPQExpBuffer(tbloids);
 7945                          8790                 :            185 : }
                               8791                 :                : 
                               8792                 :                : /*
                               8793                 :                :  * getEventTriggers
                               8794                 :                :  *    get information about event triggers
                               8795                 :                :  */
                               8796                 :                : void
  431 nathan@postgresql.or     8797                 :            185 : getEventTriggers(Archive *fout)
                               8798                 :                : {
                               8799                 :                :     int         i;
                               8800                 :                :     PQExpBuffer query;
                               8801                 :                :     PGresult   *res;
                               8802                 :                :     EventTriggerInfo *evtinfo;
                               8803                 :                :     int         i_tableoid,
                               8804                 :                :                 i_oid,
                               8805                 :                :                 i_evtname,
                               8806                 :                :                 i_evtevent,
                               8807                 :                :                 i_evtowner,
                               8808                 :                :                 i_evttags,
                               8809                 :                :                 i_evtfname,
                               8810                 :                :                 i_evtenabled;
                               8811                 :                :     int         ntups;
                               8812                 :                : 
                               8813                 :                :     /* Before 9.3, there are no event triggers */
 4798 rhaas@postgresql.org     8814         [ -  + ]:            185 :     if (fout->remoteVersion < 90300)
  431 nathan@postgresql.or     8815                 :UBC           0 :         return;
                               8816                 :                : 
 4437 sfrost@snowman.net       8817                 :CBC         185 :     query = createPQExpBuffer();
                               8818                 :                : 
 1096 drowley@postgresql.o     8819                 :            185 :     appendPQExpBufferStr(query,
                               8820                 :                :                          "SELECT e.tableoid, e.oid, evtname, evtenabled, "
                               8821                 :                :                          "evtevent, evtowner, "
                               8822                 :                :                          "array_to_string(array("
                               8823                 :                :                          "select quote_literal(x) "
                               8824                 :                :                          " from unnest(evttags) as t(x)), ', ') as evttags, "
                               8825                 :                :                          "e.evtfoid::regproc as evtfname "
                               8826                 :                :                          "FROM pg_event_trigger e "
                               8827                 :                :                          "ORDER BY e.oid");
                               8828                 :                : 
 4798 rhaas@postgresql.org     8829                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8830                 :                : 
                               8831                 :            185 :     ntups = PQntuples(res);
                               8832                 :                : 
                               8833                 :            185 :     evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
                               8834                 :                : 
                               8835                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               8836                 :            185 :     i_oid = PQfnumber(res, "oid");
                               8837                 :            185 :     i_evtname = PQfnumber(res, "evtname");
                               8838                 :            185 :     i_evtevent = PQfnumber(res, "evtevent");
                               8839                 :            185 :     i_evtowner = PQfnumber(res, "evtowner");
                               8840                 :            185 :     i_evttags = PQfnumber(res, "evttags");
                               8841                 :            185 :     i_evtfname = PQfnumber(res, "evtfname");
                               8842                 :            185 :     i_evtenabled = PQfnumber(res, "evtenabled");
                               8843                 :                : 
                               8844         [ +  + ]:            243 :     for (i = 0; i < ntups; i++)
                               8845                 :                :     {
                               8846                 :             58 :         evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
                               8847                 :             58 :         evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8848                 :             58 :         evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8849                 :             58 :         AssignDumpId(&evtinfo[i].dobj);
                               8850                 :             58 :         evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8851                 :             58 :         evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8852                 :             58 :         evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
 1345 tgl@sss.pgh.pa.us        8853                 :             58 :         evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
 4798 rhaas@postgresql.org     8854                 :             58 :         evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
                               8855                 :             58 :         evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
                               8856                 :             58 :         evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
                               8857                 :                : 
                               8858                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       8859                 :             58 :         selectDumpableObject(&(evtinfo[i].dobj), fout);
                               8860                 :                :     }
                               8861                 :                : 
 4798 rhaas@postgresql.org     8862                 :            185 :     PQclear(res);
                               8863                 :                : 
                               8864                 :            185 :     destroyPQExpBuffer(query);
                               8865                 :                : }
                               8866                 :                : 
                               8867                 :                : /*
                               8868                 :                :  * getProcLangs
                               8869                 :                :  *    get basic information about every procedural language in the system
                               8870                 :                :  *
                               8871                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               8872                 :                :  * findFuncByOid().
                               8873                 :                :  */
                               8874                 :                : void
  431 nathan@postgresql.or     8875                 :            185 : getProcLangs(Archive *fout)
                               8876                 :                : {
                               8877                 :                :     PGresult   *res;
                               8878                 :                :     int         ntups;
                               8879                 :                :     int         i;
 7945 tgl@sss.pgh.pa.us        8880                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               8881                 :                :     ProcLangInfo *planginfo;
                               8882                 :                :     int         i_tableoid;
                               8883                 :                :     int         i_oid;
                               8884                 :                :     int         i_lanname;
                               8885                 :                :     int         i_lanpltrusted;
                               8886                 :                :     int         i_lanplcallfoid;
                               8887                 :                :     int         i_laninline;
                               8888                 :                :     int         i_lanvalidator;
                               8889                 :                :     int         i_lanacl;
                               8890                 :                :     int         i_acldefault;
                               8891                 :                :     int         i_lanowner;
                               8892                 :                : 
 1096 drowley@postgresql.o     8893                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8894                 :                :                          "lanname, lanpltrusted, lanplcallfoid, "
                               8895                 :                :                          "laninline, lanvalidator, "
                               8896                 :                :                          "lanacl, "
                               8897                 :                :                          "acldefault('l', lanowner) AS acldefault, "
                               8898                 :                :                          "lanowner "
                               8899                 :                :                          "FROM pg_language "
                               8900                 :                :                          "WHERE lanispl "
                               8901                 :                :                          "ORDER BY oid");
                               8902                 :                : 
 4960 rhaas@postgresql.org     8903                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8904                 :                : 
 7945 tgl@sss.pgh.pa.us        8905                 :            185 :     ntups = PQntuples(res);
                               8906                 :                : 
 5034 bruce@momjian.us         8907                 :            185 :     planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
                               8908                 :                : 
 7945 tgl@sss.pgh.pa.us        8909                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               8910                 :            185 :     i_oid = PQfnumber(res, "oid");
                               8911                 :            185 :     i_lanname = PQfnumber(res, "lanname");
                               8912                 :            185 :     i_lanpltrusted = PQfnumber(res, "lanpltrusted");
                               8913                 :            185 :     i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
 5828                          8914                 :            185 :     i_laninline = PQfnumber(res, "laninline");
 7217                          8915                 :            185 :     i_lanvalidator = PQfnumber(res, "lanvalidator");
                               8916                 :            185 :     i_lanacl = PQfnumber(res, "lanacl");
 1370                          8917                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
 7217                          8918                 :            185 :     i_lanowner = PQfnumber(res, "lanowner");
                               8919                 :                : 
 7945                          8920         [ +  + ]:            421 :     for (i = 0; i < ntups; i++)
                               8921                 :                :     {
                               8922                 :            236 :         planginfo[i].dobj.objType = DO_PROCLANG;
                               8923                 :            236 :         planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8924                 :            236 :         planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8925                 :            236 :         AssignDumpId(&planginfo[i].dobj);
                               8926                 :                : 
 5034 bruce@momjian.us         8927                 :            236 :         planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
 1370 tgl@sss.pgh.pa.us        8928                 :            236 :         planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
                               8929                 :            236 :         planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               8930                 :            236 :         planginfo[i].dacl.privtype = 0;
                               8931                 :            236 :         planginfo[i].dacl.initprivs = NULL;
 7945                          8932                 :            236 :         planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
                               8933                 :            236 :         planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
 3680                          8934                 :            236 :         planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
                               8935                 :            236 :         planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
 1345                          8936                 :            236 :         planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
                               8937                 :                : 
                               8938                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       8939                 :            236 :         selectDumpableProcLang(&(planginfo[i]), fout);
                               8940                 :                : 
                               8941                 :                :         /* Mark whether language has an ACL */
 1370 tgl@sss.pgh.pa.us        8942         [ +  + ]:            236 :         if (!PQgetisnull(res, i, i_lanacl))
                               8943                 :             51 :             planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               8944                 :                :     }
                               8945                 :                : 
 7945                          8946                 :            185 :     PQclear(res);
                               8947                 :                : 
                               8948                 :            185 :     destroyPQExpBuffer(query);
                               8949                 :            185 : }
                               8950                 :                : 
                               8951                 :                : /*
                               8952                 :                :  * getCasts
                               8953                 :                :  *    get basic information about most casts in the system
                               8954                 :                :  *
                               8955                 :                :  * Skip casts from a range to its multirange, since we'll create those
                               8956                 :                :  * automatically.
                               8957                 :                :  */
                               8958                 :                : void
  431 nathan@postgresql.or     8959                 :            185 : getCasts(Archive *fout)
                               8960                 :                : {
                               8961                 :                :     PGresult   *res;
                               8962                 :                :     int         ntups;
                               8963                 :                :     int         i;
 7945 tgl@sss.pgh.pa.us        8964                 :            185 :     PQExpBuffer query = createPQExpBuffer();
                               8965                 :                :     CastInfo   *castinfo;
                               8966                 :                :     int         i_tableoid;
                               8967                 :                :     int         i_oid;
                               8968                 :                :     int         i_castsource;
                               8969                 :                :     int         i_casttarget;
                               8970                 :                :     int         i_castfunc;
                               8971                 :                :     int         i_castcontext;
                               8972                 :                :     int         i_castmethod;
                               8973                 :                : 
 1721 akorotkov@postgresql     8974         [ +  - ]:            185 :     if (fout->remoteVersion >= 140000)
                               8975                 :                :     {
                               8976                 :            185 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8977                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               8978                 :                :                              "castmethod "
                               8979                 :                :                              "FROM pg_cast c "
                               8980                 :                :                              "WHERE NOT EXISTS ( "
                               8981                 :                :                              "SELECT 1 FROM pg_range r "
                               8982                 :                :                              "WHERE c.castsource = r.rngtypid "
                               8983                 :                :                              "AND c.casttarget = r.rngmultitypid "
                               8984                 :                :                              ") "
                               8985                 :                :                              "ORDER BY 3,4");
                               8986                 :                :     }
                               8987                 :                :     else
                               8988                 :                :     {
 4310 heikki.linnakangas@i     8989                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8990                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               8991                 :                :                              "castmethod "
                               8992                 :                :                              "FROM pg_cast ORDER BY 3,4");
                               8993                 :                :     }
                               8994                 :                : 
 4960 rhaas@postgresql.org     8995                 :CBC         185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8996                 :                : 
 7945 tgl@sss.pgh.pa.us        8997                 :            185 :     ntups = PQntuples(res);
                               8998                 :                : 
 5034 bruce@momjian.us         8999                 :            185 :     castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
                               9000                 :                : 
 7945 tgl@sss.pgh.pa.us        9001                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               9002                 :            185 :     i_oid = PQfnumber(res, "oid");
                               9003                 :            185 :     i_castsource = PQfnumber(res, "castsource");
                               9004                 :            185 :     i_casttarget = PQfnumber(res, "casttarget");
                               9005                 :            185 :     i_castfunc = PQfnumber(res, "castfunc");
                               9006                 :            185 :     i_castcontext = PQfnumber(res, "castcontext");
 6154 heikki.linnakangas@i     9007                 :            185 :     i_castmethod = PQfnumber(res, "castmethod");
                               9008                 :                : 
 7945 tgl@sss.pgh.pa.us        9009         [ +  + ]:          43938 :     for (i = 0; i < ntups; i++)
                               9010                 :                :     {
                               9011                 :                :         PQExpBufferData namebuf;
                               9012                 :                :         TypeInfo   *sTypeInfo;
                               9013                 :                :         TypeInfo   *tTypeInfo;
                               9014                 :                : 
                               9015                 :          43753 :         castinfo[i].dobj.objType = DO_CAST;
                               9016                 :          43753 :         castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9017                 :          43753 :         castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9018                 :          43753 :         AssignDumpId(&castinfo[i].dobj);
                               9019                 :          43753 :         castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
                               9020                 :          43753 :         castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
                               9021                 :          43753 :         castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
                               9022                 :          43753 :         castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
 6154 heikki.linnakangas@i     9023                 :          43753 :         castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
                               9024                 :                : 
                               9025                 :                :         /*
                               9026                 :                :          * Try to name cast as concatenation of typnames.  This is only used
                               9027                 :                :          * for purposes of sorting.  If we fail to find either type, the name
                               9028                 :                :          * will be an empty string.
                               9029                 :                :          */
 7857 tgl@sss.pgh.pa.us        9030                 :          43753 :         initPQExpBuffer(&namebuf);
                               9031                 :          43753 :         sTypeInfo = findTypeByOid(castinfo[i].castsource);
                               9032                 :          43753 :         tTypeInfo = findTypeByOid(castinfo[i].casttarget);
                               9033   [ +  -  +  - ]:          43753 :         if (sTypeInfo && tTypeInfo)
                               9034                 :          43753 :             appendPQExpBuffer(&namebuf, "%s %s",
                               9035                 :                :                               sTypeInfo->dobj.name, tTypeInfo->dobj.name);
                               9036                 :          43753 :         castinfo[i].dobj.name = namebuf.data;
                               9037                 :                : 
                               9038                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       9039                 :          43753 :         selectDumpableCast(&(castinfo[i]), fout);
                               9040                 :                :     }
                               9041                 :                : 
 7945 tgl@sss.pgh.pa.us        9042                 :            185 :     PQclear(res);
                               9043                 :                : 
                               9044                 :            185 :     destroyPQExpBuffer(query);
                               9045                 :            185 : }
                               9046                 :                : 
                               9047                 :                : static char *
 3786 peter_e@gmx.net          9048                 :            100 : get_language_name(Archive *fout, Oid langid)
                               9049                 :                : {
                               9050                 :                :     PQExpBuffer query;
                               9051                 :                :     PGresult   *res;
                               9052                 :                :     char       *lanname;
                               9053                 :                : 
                               9054                 :            100 :     query = createPQExpBuffer();
                               9055                 :            100 :     appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
                               9056                 :            100 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                               9057                 :            100 :     lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
                               9058                 :            100 :     destroyPQExpBuffer(query);
                               9059                 :            100 :     PQclear(res);
                               9060                 :                : 
                               9061                 :            100 :     return lanname;
                               9062                 :                : }
                               9063                 :                : 
                               9064                 :                : /*
                               9065                 :                :  * getTransforms
                               9066                 :                :  *    get basic information about every transform in the system
                               9067                 :                :  */
                               9068                 :                : void
  431 nathan@postgresql.or     9069                 :            185 : getTransforms(Archive *fout)
                               9070                 :                : {
                               9071                 :                :     PGresult   *res;
                               9072                 :                :     int         ntups;
                               9073                 :                :     int         i;
                               9074                 :                :     PQExpBuffer query;
                               9075                 :                :     TransformInfo *transforminfo;
                               9076                 :                :     int         i_tableoid;
                               9077                 :                :     int         i_oid;
                               9078                 :                :     int         i_trftype;
                               9079                 :                :     int         i_trflang;
                               9080                 :                :     int         i_trffromsql;
                               9081                 :                :     int         i_trftosql;
                               9082                 :                : 
                               9083                 :                :     /* Transforms didn't exist pre-9.5 */
 3786 peter_e@gmx.net          9084         [ -  + ]:            185 :     if (fout->remoteVersion < 90500)
  431 nathan@postgresql.or     9085                 :UBC           0 :         return;
                               9086                 :                : 
 3775 magnus@hagander.net      9087                 :CBC         185 :     query = createPQExpBuffer();
                               9088                 :                : 
 2256 drowley@postgresql.o     9089                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               9090                 :                :                          "trftype, trflang, trffromsql::oid, trftosql::oid "
                               9091                 :                :                          "FROM pg_transform "
                               9092                 :                :                          "ORDER BY 3,4");
                               9093                 :                : 
 3786 peter_e@gmx.net          9094                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9095                 :                : 
                               9096                 :            185 :     ntups = PQntuples(res);
                               9097                 :                : 
                               9098                 :            185 :     transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
                               9099                 :                : 
                               9100                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                               9101                 :            185 :     i_oid = PQfnumber(res, "oid");
                               9102                 :            185 :     i_trftype = PQfnumber(res, "trftype");
                               9103                 :            185 :     i_trflang = PQfnumber(res, "trflang");
                               9104                 :            185 :     i_trffromsql = PQfnumber(res, "trffromsql");
                               9105                 :            185 :     i_trftosql = PQfnumber(res, "trftosql");
                               9106                 :                : 
                               9107         [ +  + ]:            243 :     for (i = 0; i < ntups; i++)
                               9108                 :                :     {
                               9109                 :                :         PQExpBufferData namebuf;
                               9110                 :                :         TypeInfo   *typeInfo;
                               9111                 :                :         char       *lanname;
                               9112                 :                : 
                               9113                 :             58 :         transforminfo[i].dobj.objType = DO_TRANSFORM;
                               9114                 :             58 :         transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9115                 :             58 :         transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9116                 :             58 :         AssignDumpId(&transforminfo[i].dobj);
                               9117                 :             58 :         transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
                               9118                 :             58 :         transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
                               9119                 :             58 :         transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
                               9120                 :             58 :         transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
                               9121                 :                : 
                               9122                 :                :         /*
                               9123                 :                :          * Try to name transform as concatenation of type and language name.
                               9124                 :                :          * This is only used for purposes of sorting.  If we fail to find
                               9125                 :                :          * either, the name will be an empty string.
                               9126                 :                :          */
                               9127                 :             58 :         initPQExpBuffer(&namebuf);
                               9128                 :             58 :         typeInfo = findTypeByOid(transforminfo[i].trftype);
                               9129                 :             58 :         lanname = get_language_name(fout, transforminfo[i].trflang);
                               9130   [ +  -  +  - ]:             58 :         if (typeInfo && lanname)
                               9131                 :             58 :             appendPQExpBuffer(&namebuf, "%s %s",
                               9132                 :                :                               typeInfo->dobj.name, lanname);
                               9133                 :             58 :         transforminfo[i].dobj.name = namebuf.data;
 3709 tgl@sss.pgh.pa.us        9134                 :             58 :         free(lanname);
                               9135                 :                : 
                               9136                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net       9137                 :             58 :         selectDumpableObject(&(transforminfo[i].dobj), fout);
                               9138                 :                :     }
                               9139                 :                : 
 3786 peter_e@gmx.net          9140                 :            185 :     PQclear(res);
                               9141                 :                : 
                               9142                 :            185 :     destroyPQExpBuffer(query);
                               9143                 :                : }
                               9144                 :                : 
                               9145                 :                : /*
                               9146                 :                :  * getTableAttrs -
                               9147                 :                :  *    for each interesting table, read info about its attributes
                               9148                 :                :  *    (names, types, default values, CHECK constraints, etc)
                               9149                 :                :  *
                               9150                 :                :  *  modifies tblinfo
                               9151                 :                :  */
                               9152                 :                : void
 3524 tgl@sss.pgh.pa.us        9153                 :            185 : getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                               9154                 :                : {
                               9155                 :            185 :     DumpOptions *dopt = fout->dopt;
 7945                          9156                 :            185 :     PQExpBuffer q = createPQExpBuffer();
 1370                          9157                 :            185 :     PQExpBuffer tbloids = createPQExpBuffer();
                               9158                 :            185 :     PQExpBuffer checkoids = createPQExpBuffer();
  152 alvherre@alvh.no-ip.     9159                 :            185 :     PQExpBuffer invalidnotnulloids = NULL;
                               9160                 :                :     PGresult   *res;
                               9161                 :                :     int         ntups;
                               9162                 :                :     int         curtblindx;
                               9163                 :                :     int         i_attrelid;
                               9164                 :                :     int         i_attnum;
                               9165                 :                :     int         i_attname;
                               9166                 :                :     int         i_atttypname;
                               9167                 :                :     int         i_attstattarget;
                               9168                 :                :     int         i_attstorage;
                               9169                 :                :     int         i_typstorage;
                               9170                 :                :     int         i_attidentity;
                               9171                 :                :     int         i_attgenerated;
                               9172                 :                :     int         i_attisdropped;
                               9173                 :                :     int         i_attlen;
                               9174                 :                :     int         i_attalign;
                               9175                 :                :     int         i_attislocal;
                               9176                 :                :     int         i_notnull_name;
                               9177                 :                :     int         i_notnull_comment;
                               9178                 :                :     int         i_notnull_noinherit;
                               9179                 :                :     int         i_notnull_islocal;
                               9180                 :                :     int         i_notnull_invalidoid;
                               9181                 :                :     int         i_attoptions;
                               9182                 :                :     int         i_attcollation;
                               9183                 :                :     int         i_attcompression;
                               9184                 :                :     int         i_attfdwoptions;
                               9185                 :                :     int         i_attmissingval;
                               9186                 :                :     int         i_atthasdef;
                               9187                 :                : 
                               9188                 :                :     /*
                               9189                 :                :      * We want to perform just one query against pg_attribute, and then just
                               9190                 :                :      * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
                               9191                 :                :      * (for CHECK constraints and for NOT NULL constraints).  However, we
                               9192                 :                :      * mustn't try to select every row of those catalogs and then sort it out
                               9193                 :                :      * on the client side, because some of the server-side functions we need
                               9194                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               9195                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               9196                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               9197                 :                :      */
 1370 tgl@sss.pgh.pa.us        9198                 :            185 :     appendPQExpBufferChar(tbloids, '{');
                               9199                 :            185 :     appendPQExpBufferChar(checkoids, '{');
 1885 peter@eisentraut.org     9200         [ +  + ]:          49228 :     for (int i = 0; i < numTables; i++)
                               9201                 :                :     {
 8403 bruce@momjian.us         9202                 :          49043 :         TableInfo  *tbinfo = &tblinfo[i];
                               9203                 :                : 
                               9204                 :                :         /* Don't bother to collect info for sequences */
 8419 tgl@sss.pgh.pa.us        9205         [ +  + ]:          49043 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
10226 bruce@momjian.us         9206                 :            656 :             continue;
                               9207                 :                : 
                               9208                 :                :         /*
                               9209                 :                :          * Don't bother with uninteresting tables, either.  For binary
                               9210                 :                :          * upgrades, this is bypassed for pg_largeobject_metadata and
                               9211                 :                :          * pg_shdepend so that the columns names are collected for the
                               9212                 :                :          * corresponding COPY commands.  Restoring the data for those catalogs
                               9213                 :                :          * is faster than restoring the equivalent set of large object
                               9214                 :                :          * commands.  We can only do this for upgrades from v12 and newer; in
                               9215                 :                :          * older versions, pg_largeobject_metadata was created WITH OIDS, so
                               9216                 :                :          * the OID column is hidden and won't be dumped.
                               9217                 :                :          */
   50 nathan@postgresql.or     9218         [ +  + ]:GNC       48387 :         if (!tbinfo->interesting &&
                               9219   [ +  +  +  - ]:          41420 :             !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
                               9220         [ +  + ]:           7722 :               (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
                               9221         [ +  + ]:           7686 :                tbinfo->dobj.catId.oid == SharedDependRelationId)))
 8520 tgl@sss.pgh.pa.us        9222                 :CBC       41348 :             continue;
                               9223                 :                : 
                               9224                 :                :         /* OK, we need info for this table */
 1370                          9225         [ +  + ]:           7039 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               9226                 :           6898 :             appendPQExpBufferChar(tbloids, ',');
                               9227                 :           7039 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               9228                 :                : 
                               9229         [ +  + ]:           7039 :         if (tbinfo->ncheck > 0)
                               9230                 :                :         {
                               9231                 :                :             /* Also make a list of the ones with check constraints */
                               9232         [ +  + ]:            586 :             if (checkoids->len > 1) /* do we have more than the '{'? */
                               9233                 :            511 :                 appendPQExpBufferChar(checkoids, ',');
                               9234                 :            586 :             appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
                               9235                 :                :         }
                               9236                 :                :     }
                               9237                 :            185 :     appendPQExpBufferChar(tbloids, '}');
                               9238                 :            185 :     appendPQExpBufferChar(checkoids, '}');
                               9239                 :                : 
                               9240                 :                :     /*
                               9241                 :                :      * Find all the user attributes and their types.
                               9242                 :                :      *
                               9243                 :                :      * Since we only want to dump COLLATE clauses for attributes whose
                               9244                 :                :      * collation is different from their type's default, we use a CASE here to
                               9245                 :                :      * suppress uninteresting attcollations cheaply.
                               9246                 :                :      */
                               9247                 :            185 :     appendPQExpBufferStr(q,
                               9248                 :                :                          "SELECT\n"
                               9249                 :                :                          "a.attrelid,\n"
                               9250                 :                :                          "a.attnum,\n"
                               9251                 :                :                          "a.attname,\n"
                               9252                 :                :                          "a.attstattarget,\n"
                               9253                 :                :                          "a.attstorage,\n"
                               9254                 :                :                          "t.typstorage,\n"
                               9255                 :                :                          "a.atthasdef,\n"
                               9256                 :                :                          "a.attisdropped,\n"
                               9257                 :                :                          "a.attlen,\n"
                               9258                 :                :                          "a.attalign,\n"
                               9259                 :                :                          "a.attislocal,\n"
                               9260                 :                :                          "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
                               9261                 :                :                          "array_to_string(a.attoptions, ', ') AS attoptions,\n"
                               9262                 :                :                          "CASE WHEN a.attcollation <> t.typcollation "
                               9263                 :                :                          "THEN a.attcollation ELSE 0 END AS attcollation,\n"
                               9264                 :                :                          "pg_catalog.array_to_string(ARRAY("
                               9265                 :                :                          "SELECT pg_catalog.quote_ident(option_name) || "
                               9266                 :                :                          "' ' || pg_catalog.quote_literal(option_value) "
                               9267                 :                :                          "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
                               9268                 :                :                          "ORDER BY option_name"
                               9269                 :                :                          "), E',\n    ') AS attfdwoptions,\n");
                               9270                 :                : 
                               9271                 :                :     /*
                               9272                 :                :      * Find out any NOT NULL markings for each column.  In 18 and up we read
                               9273                 :                :      * pg_constraint to obtain the constraint name, and for valid constraints
                               9274                 :                :      * also pg_description to obtain its comment.  notnull_noinherit is set
                               9275                 :                :      * according to the NO INHERIT property.  For versions prior to 18, we
                               9276                 :                :      * store an empty string as the name when a constraint is marked as
                               9277                 :                :      * attnotnull (this cues dumpTableSchema to print the NOT NULL clause
                               9278                 :                :      * without a name); also, such cases are never NO INHERIT.
                               9279                 :                :      *
                               9280                 :                :      * For invalid constraints, we need to store their OIDs for processing
                               9281                 :                :      * elsewhere, so we bring the pg_constraint.oid value when the constraint
                               9282                 :                :      * is invalid, and NULL otherwise.  Their comments are handled not here
                               9283                 :                :      * but by collectComments, because they're their own dumpable object.
                               9284                 :                :      *
                               9285                 :                :      * We track in notnull_islocal whether the constraint was defined directly
                               9286                 :                :      * in this table or via an ancestor, for binary upgrade.  flagInhAttrs
                               9287                 :                :      * might modify this later; that routine is also in charge of determining
                               9288                 :                :      * the correct inhcount.
                               9289                 :                :      */
  302 alvherre@alvh.no-ip.     9290         [ +  - ]:            185 :     if (fout->remoteVersion >= 180000)
                               9291                 :            185 :         appendPQExpBufferStr(q,
                               9292                 :                :                              "co.conname AS notnull_name,\n"
                               9293                 :                :                              "CASE WHEN co.convalidated THEN pt.description"
                               9294                 :                :                              " ELSE NULL END AS notnull_comment,\n"
                               9295                 :                :                              "CASE WHEN NOT co.convalidated THEN co.oid "
                               9296                 :                :                              "ELSE NULL END AS notnull_invalidoid,\n"
                               9297                 :                :                              "co.connoinherit AS notnull_noinherit,\n"
                               9298                 :                :                              "co.conislocal AS notnull_islocal,\n");
                               9299                 :                :     else
  302 alvherre@alvh.no-ip.     9300                 :UBC           0 :         appendPQExpBufferStr(q,
                               9301                 :                :                              "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
                               9302                 :                :                              "NULL AS notnull_comment,\n"
                               9303                 :                :                              "NULL AS notnull_invalidoid,\n"
                               9304                 :                :                              "false AS notnull_noinherit,\n"
                               9305                 :                :                              "a.attislocal AS notnull_islocal,\n");
                               9306                 :                : 
 1370 tgl@sss.pgh.pa.us        9307         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 140000)
                               9308                 :            185 :         appendPQExpBufferStr(q,
                               9309                 :                :                              "a.attcompression AS attcompression,\n");
                               9310                 :                :     else
 1370 tgl@sss.pgh.pa.us        9311                 :UBC           0 :         appendPQExpBufferStr(q,
                               9312                 :                :                              "'' AS attcompression,\n");
                               9313                 :                : 
 1370 tgl@sss.pgh.pa.us        9314         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 100000)
                               9315                 :            185 :         appendPQExpBufferStr(q,
                               9316                 :                :                              "a.attidentity,\n");
                               9317                 :                :     else
 1370 tgl@sss.pgh.pa.us        9318                 :UBC           0 :         appendPQExpBufferStr(q,
                               9319                 :                :                              "'' AS attidentity,\n");
                               9320                 :                : 
 1370 tgl@sss.pgh.pa.us        9321         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 110000)
                               9322                 :            185 :         appendPQExpBufferStr(q,
                               9323                 :                :                              "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
                               9324                 :                :                              "THEN a.attmissingval ELSE null END AS attmissingval,\n");
                               9325                 :                :     else
 1370 tgl@sss.pgh.pa.us        9326                 :UBC           0 :         appendPQExpBufferStr(q,
                               9327                 :                :                              "NULL AS attmissingval,\n");
                               9328                 :                : 
 1370 tgl@sss.pgh.pa.us        9329         [ +  - ]:CBC         185 :     if (fout->remoteVersion >= 120000)
                               9330                 :            185 :         appendPQExpBufferStr(q,
                               9331                 :                :                              "a.attgenerated\n");
                               9332                 :                :     else
 1370 tgl@sss.pgh.pa.us        9333                 :UBC           0 :         appendPQExpBufferStr(q,
                               9334                 :                :                              "'' AS attgenerated\n");
                               9335                 :                : 
                               9336                 :                :     /* need left join to pg_type to not fail on dropped columns ... */
 1370 tgl@sss.pgh.pa.us        9337                 :CBC         185 :     appendPQExpBuffer(q,
                               9338                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9339                 :                :                       "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
                               9340                 :                :                       "LEFT JOIN pg_catalog.pg_type t "
                               9341                 :                :                       "ON (a.atttypid = t.oid)\n",
                               9342                 :                :                       tbloids->data);
                               9343                 :                : 
                               9344                 :                :     /*
                               9345                 :                :      * In versions 18 and up, we need pg_constraint for explicit NOT NULL
                               9346                 :                :      * entries and pg_description to get their comments.
                               9347                 :                :      */
  302 alvherre@alvh.no-ip.     9348         [ +  - ]:            185 :     if (fout->remoteVersion >= 180000)
                               9349                 :            185 :         appendPQExpBufferStr(q,
                               9350                 :                :                              " LEFT JOIN pg_catalog.pg_constraint co ON "
                               9351                 :                :                              "(a.attrelid = co.conrelid\n"
                               9352                 :                :                              "   AND co.contype = 'n' AND "
                               9353                 :                :                              "co.conkey = array[a.attnum])\n"
                               9354                 :                :                              " LEFT JOIN pg_catalog.pg_description pt ON "
                               9355                 :                :                              "(pt.classoid = co.tableoid AND pt.objoid = co.oid)\n");
                               9356                 :                : 
                               9357                 :            185 :     appendPQExpBufferStr(q,
                               9358                 :                :                          "WHERE a.attnum > 0::pg_catalog.int2\n"
                               9359                 :                :                          "ORDER BY a.attrelid, a.attnum");
                               9360                 :                : 
 1370 tgl@sss.pgh.pa.us        9361                 :            185 :     res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9362                 :                : 
                               9363                 :            185 :     ntups = PQntuples(res);
                               9364                 :                : 
                               9365                 :            185 :     i_attrelid = PQfnumber(res, "attrelid");
                               9366                 :            185 :     i_attnum = PQfnumber(res, "attnum");
                               9367                 :            185 :     i_attname = PQfnumber(res, "attname");
                               9368                 :            185 :     i_atttypname = PQfnumber(res, "atttypname");
                               9369                 :            185 :     i_attstattarget = PQfnumber(res, "attstattarget");
                               9370                 :            185 :     i_attstorage = PQfnumber(res, "attstorage");
                               9371                 :            185 :     i_typstorage = PQfnumber(res, "typstorage");
                               9372                 :            185 :     i_attidentity = PQfnumber(res, "attidentity");
                               9373                 :            185 :     i_attgenerated = PQfnumber(res, "attgenerated");
                               9374                 :            185 :     i_attisdropped = PQfnumber(res, "attisdropped");
                               9375                 :            185 :     i_attlen = PQfnumber(res, "attlen");
                               9376                 :            185 :     i_attalign = PQfnumber(res, "attalign");
                               9377                 :            185 :     i_attislocal = PQfnumber(res, "attislocal");
  302 alvherre@alvh.no-ip.     9378                 :            185 :     i_notnull_name = PQfnumber(res, "notnull_name");
   72 alvherre@kurilemu.de     9379                 :            185 :     i_notnull_comment = PQfnumber(res, "notnull_comment");
  152 alvherre@alvh.no-ip.     9380                 :            185 :     i_notnull_invalidoid = PQfnumber(res, "notnull_invalidoid");
  302                          9381                 :            185 :     i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
                               9382                 :            185 :     i_notnull_islocal = PQfnumber(res, "notnull_islocal");
 1370 tgl@sss.pgh.pa.us        9383                 :            185 :     i_attoptions = PQfnumber(res, "attoptions");
                               9384                 :            185 :     i_attcollation = PQfnumber(res, "attcollation");
                               9385                 :            185 :     i_attcompression = PQfnumber(res, "attcompression");
                               9386                 :            185 :     i_attfdwoptions = PQfnumber(res, "attfdwoptions");
                               9387                 :            185 :     i_attmissingval = PQfnumber(res, "attmissingval");
                               9388                 :            185 :     i_atthasdef = PQfnumber(res, "atthasdef");
                               9389                 :                : 
                               9390                 :                :     /* Within the next loop, we'll accumulate OIDs of tables with defaults */
  878 alvherre@alvh.no-ip.     9391                 :            185 :     resetPQExpBuffer(tbloids);
                               9392                 :            185 :     appendPQExpBufferChar(tbloids, '{');
                               9393                 :                : 
                               9394                 :                :     /*
                               9395                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               9396                 :                :      * r is handled by the inner loop.
                               9397                 :                :      */
 1370 tgl@sss.pgh.pa.us        9398                 :            185 :     curtblindx = -1;
                               9399         [ +  + ]:           7068 :     for (int r = 0; r < ntups;)
                               9400                 :                :     {
                               9401                 :           6883 :         Oid         attrelid = atooid(PQgetvalue(res, r, i_attrelid));
                               9402                 :           6883 :         TableInfo  *tbinfo = NULL;
                               9403                 :                :         int         numatts;
                               9404                 :                :         bool        hasdefaults;
                               9405                 :                : 
                               9406                 :                :         /* Count rows for this table */
                               9407         [ +  + ]:          25248 :         for (numatts = 1; numatts < ntups - r; numatts++)
                               9408         [ +  + ]:          25110 :             if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
                               9409                 :           6745 :                 break;
                               9410                 :                : 
                               9411                 :                :         /*
                               9412                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               9413                 :                :          * order.
                               9414                 :                :          */
                               9415         [ +  - ]:          33963 :         while (++curtblindx < numTables)
                               9416                 :                :         {
                               9417                 :          33963 :             tbinfo = &tblinfo[curtblindx];
                               9418         [ +  + ]:          33963 :             if (tbinfo->dobj.catId.oid == attrelid)
                               9419                 :           6883 :                 break;
                               9420                 :                :         }
                               9421         [ -  + ]:           6883 :         if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        9422                 :UBC           0 :             pg_fatal("unrecognized table OID %u", attrelid);
                               9423                 :                :         /* cross-check that we only got requested tables */
 1370 tgl@sss.pgh.pa.us        9424         [ +  - ]:CBC        6883 :         if (tbinfo->relkind == RELKIND_SEQUENCE ||
   50 nathan@postgresql.or     9425         [ +  + ]:GNC        6883 :             (!tbinfo->interesting &&
                               9426   [ +  -  +  - ]:             72 :              !(fout->dopt->binary_upgrade && fout->remoteVersion >= 120000 &&
                               9427         [ +  + ]:             72 :                (tbinfo->dobj.catId.oid == LargeObjectMetadataRelationId ||
                               9428         [ -  + ]:             36 :                 tbinfo->dobj.catId.oid == SharedDependRelationId))))
 1247 tgl@sss.pgh.pa.us        9429                 :UBC           0 :             pg_fatal("unexpected column data for table \"%s\"",
                               9430                 :                :                      tbinfo->dobj.name);
                               9431                 :                : 
                               9432                 :                :         /* Save data for this table */
 1370 tgl@sss.pgh.pa.us        9433                 :CBC        6883 :         tbinfo->numatts = numatts;
                               9434                 :           6883 :         tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
                               9435                 :           6883 :         tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
                               9436                 :           6883 :         tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
                               9437                 :           6883 :         tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
                               9438                 :           6883 :         tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
                               9439                 :           6883 :         tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
                               9440                 :           6883 :         tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
                               9441                 :           6883 :         tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
                               9442                 :           6883 :         tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
                               9443                 :           6883 :         tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
                               9444                 :           6883 :         tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
                               9445                 :           6883 :         tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               9446                 :           6883 :         tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
                               9447                 :           6883 :         tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
                               9448                 :           6883 :         tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               9449                 :           6883 :         tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
  302 alvherre@alvh.no-ip.     9450                 :           6883 :         tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
   72 alvherre@kurilemu.de     9451                 :           6883 :         tbinfo->notnull_comment = (char **) pg_malloc(numatts * sizeof(char *));
  131                          9452                 :           6883 :         tbinfo->notnull_invalid = (bool *) pg_malloc(numatts * sizeof(bool));
  302 alvherre@alvh.no-ip.     9453                 :           6883 :         tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
                               9454                 :           6883 :         tbinfo->notnull_islocal = (bool *) pg_malloc(numatts * sizeof(bool));
 1370 tgl@sss.pgh.pa.us        9455                 :           6883 :         tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
 8520                          9456                 :           6883 :         hasdefaults = false;
                               9457                 :                : 
 1370                          9458         [ +  + ]:          32131 :         for (int j = 0; j < numatts; j++, r++)
                               9459                 :                :         {
                               9460         [ -  + ]:          25248 :             if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
 1247 tgl@sss.pgh.pa.us        9461                 :UBC           0 :                 pg_fatal("invalid column numbering in table \"%s\"",
                               9462                 :                :                          tbinfo->dobj.name);
 1370 tgl@sss.pgh.pa.us        9463                 :CBC       25248 :             tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
                               9464                 :          25248 :             tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
  602 peter@eisentraut.org     9465         [ +  + ]:          25248 :             if (PQgetisnull(res, r, i_attstattarget))
                               9466                 :          25202 :                 tbinfo->attstattarget[j] = -1;
                               9467                 :                :             else
                               9468                 :             46 :                 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
 1370 tgl@sss.pgh.pa.us        9469                 :          25248 :             tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
                               9470                 :          25248 :             tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
                               9471                 :          25248 :             tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
                               9472                 :          25248 :             tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
 3075 peter_e@gmx.net          9473   [ +  +  +  + ]:          25248 :             tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
 1370 tgl@sss.pgh.pa.us        9474                 :          25248 :             tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
                               9475                 :          25248 :             tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
                               9476                 :          25248 :             tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
                               9477                 :          25248 :             tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
                               9478                 :                : 
                               9479                 :                :             /* Handle not-null constraint name and flags */
  302 alvherre@alvh.no-ip.     9480                 :          25248 :             determineNotNullFlags(fout, res, r,
                               9481                 :                :                                   tbinfo, j,
                               9482                 :                :                                   i_notnull_name,
                               9483                 :                :                                   i_notnull_comment,
                               9484                 :                :                                   i_notnull_invalidoid,
                               9485                 :                :                                   i_notnull_noinherit,
                               9486                 :                :                                   i_notnull_islocal,
                               9487                 :                :                                   &invalidnotnulloids);
                               9488                 :                : 
   72 alvherre@kurilemu.de     9489                 :          25248 :             tbinfo->notnull_comment[j] = PQgetisnull(res, r, i_notnull_comment) ?
                               9490         [ +  + ]:          25248 :                 NULL : pg_strdup(PQgetvalue(res, r, i_notnull_comment));
 1370 tgl@sss.pgh.pa.us        9491                 :          25248 :             tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
                               9492                 :          25248 :             tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
                               9493                 :          25248 :             tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
                               9494                 :          25248 :             tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
                               9495                 :          25248 :             tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
 7678 bruce@momjian.us         9496                 :          25248 :             tbinfo->attrdefs[j] = NULL; /* fix below */
 1370 tgl@sss.pgh.pa.us        9497         [ +  + ]:          25248 :             if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
 8520                          9498                 :           1364 :                 hasdefaults = true;
                               9499                 :                :         }
                               9500                 :                : 
 1370                          9501         [ +  + ]:           6883 :         if (hasdefaults)
                               9502                 :                :         {
                               9503                 :                :             /* Collect OIDs of interesting tables that have defaults */
  878 alvherre@alvh.no-ip.     9504         [ +  + ]:           1018 :             if (tbloids->len > 1) /* do we have more than the '{'? */
                               9505                 :            944 :                 appendPQExpBufferChar(tbloids, ',');
                               9506                 :           1018 :             appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               9507                 :                :         }
                               9508                 :                :     }
                               9509                 :                : 
                               9510                 :                :     /* If invalidnotnulloids has any data, finalize it */
  152                          9511         [ +  + ]:            185 :     if (invalidnotnulloids != NULL)
                               9512                 :             49 :         appendPQExpBufferChar(invalidnotnulloids, '}');
                               9513                 :                : 
 1370 tgl@sss.pgh.pa.us        9514                 :            185 :     PQclear(res);
                               9515                 :                : 
                               9516                 :                :     /*
                               9517                 :                :      * Now get info about column defaults.  This is skipped for a data-only
                               9518                 :                :      * dump, as it is only needed for table schemas.
                               9519                 :                :      */
  285 nathan@postgresql.or     9520   [ +  +  +  + ]:            185 :     if (dopt->dumpSchema && tbloids->len > 1)
                               9521                 :                :     {
                               9522                 :                :         AttrDefInfo *attrdefs;
                               9523                 :                :         int         numDefaults;
 1370 tgl@sss.pgh.pa.us        9524                 :             66 :         TableInfo  *tbinfo = NULL;
                               9525                 :                : 
                               9526                 :             66 :         pg_log_info("finding table default expressions");
                               9527                 :                : 
  878 alvherre@alvh.no-ip.     9528                 :             66 :         appendPQExpBufferChar(tbloids, '}');
                               9529                 :                : 
 1370 tgl@sss.pgh.pa.us        9530                 :             66 :         printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
                               9531                 :                :                           "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
                               9532                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9533                 :                :                           "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
                               9534                 :                :                           "ORDER BY a.adrelid, a.adnum",
                               9535                 :                :                           tbloids->data);
                               9536                 :                : 
                               9537                 :             66 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9538                 :                : 
                               9539                 :             66 :         numDefaults = PQntuples(res);
                               9540                 :             66 :         attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
                               9541                 :                : 
                               9542                 :             66 :         curtblindx = -1;
                               9543         [ +  + ]:           1332 :         for (int j = 0; j < numDefaults; j++)
                               9544                 :                :         {
                               9545                 :           1266 :             Oid         adtableoid = atooid(PQgetvalue(res, j, 0));
                               9546                 :           1266 :             Oid         adoid = atooid(PQgetvalue(res, j, 1));
                               9547                 :           1266 :             Oid         adrelid = atooid(PQgetvalue(res, j, 2));
                               9548                 :           1266 :             int         adnum = atoi(PQgetvalue(res, j, 3));
                               9549                 :           1266 :             char       *adsrc = PQgetvalue(res, j, 4);
                               9550                 :                : 
                               9551                 :                :             /*
                               9552                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9553                 :                :              * OID order.
                               9554                 :                :              */
                               9555   [ +  +  +  + ]:           1266 :             if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
                               9556                 :                :             {
                               9557         [ +  - ]:          20267 :                 while (++curtblindx < numTables)
                               9558                 :                :                 {
                               9559                 :          20267 :                     tbinfo = &tblinfo[curtblindx];
                               9560         [ +  + ]:          20267 :                     if (tbinfo->dobj.catId.oid == adrelid)
                               9561                 :            950 :                         break;
                               9562                 :                :                 }
                               9563         [ -  + ]:            950 :                 if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        9564                 :UBC           0 :                     pg_fatal("unrecognized table OID %u", adrelid);
                               9565                 :                :             }
                               9566                 :                : 
 1370 tgl@sss.pgh.pa.us        9567   [ +  -  -  + ]:CBC        1266 :             if (adnum <= 0 || adnum > tbinfo->numatts)
 1247 tgl@sss.pgh.pa.us        9568                 :UBC           0 :                 pg_fatal("invalid adnum value %d for table \"%s\"",
                               9569                 :                :                          adnum, tbinfo->dobj.name);
                               9570                 :                : 
                               9571                 :                :             /*
                               9572                 :                :              * dropped columns shouldn't have defaults, but just in case,
                               9573                 :                :              * ignore 'em
                               9574                 :                :              */
 1370 tgl@sss.pgh.pa.us        9575         [ -  + ]:CBC        1266 :             if (tbinfo->attisdropped[adnum - 1])
 1370 tgl@sss.pgh.pa.us        9576                 :UBC           0 :                 continue;
                               9577                 :                : 
 1370 tgl@sss.pgh.pa.us        9578                 :CBC        1266 :             attrdefs[j].dobj.objType = DO_ATTRDEF;
                               9579                 :           1266 :             attrdefs[j].dobj.catId.tableoid = adtableoid;
                               9580                 :           1266 :             attrdefs[j].dobj.catId.oid = adoid;
                               9581                 :           1266 :             AssignDumpId(&attrdefs[j].dobj);
                               9582                 :           1266 :             attrdefs[j].adtable = tbinfo;
                               9583                 :           1266 :             attrdefs[j].adnum = adnum;
                               9584                 :           1266 :             attrdefs[j].adef_expr = pg_strdup(adsrc);
                               9585                 :                : 
                               9586                 :           1266 :             attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
                               9587                 :           1266 :             attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
                               9588                 :                : 
                               9589                 :           1266 :             attrdefs[j].dobj.dump = tbinfo->dobj.dump;
                               9590                 :                : 
                               9591                 :                :             /*
                               9592                 :                :              * Figure out whether the default/generation expression should be
                               9593                 :                :              * dumped as part of the main CREATE TABLE (or similar) command or
                               9594                 :                :              * as a separate ALTER TABLE (or similar) command. The preference
                               9595                 :                :              * is to put it into the CREATE command, but in some cases that's
                               9596                 :                :              * not possible.
                               9597                 :                :              */
                               9598         [ +  + ]:           1266 :             if (tbinfo->attgenerated[adnum - 1])
                               9599                 :                :             {
                               9600                 :                :                 /*
                               9601                 :                :                  * Column generation expressions cannot be dumped separately,
                               9602                 :                :                  * because there is no syntax for it.  By setting separate to
                               9603                 :                :                  * false here we prevent the "default" from being processed as
                               9604                 :                :                  * its own dumpable object.  Later, flagInhAttrs() will mark
                               9605                 :                :                  * it as not to be dumped at all, if possible (that is, if it
                               9606                 :                :                  * can be inherited from a parent).
                               9607                 :                :                  */
                               9608                 :            704 :                 attrdefs[j].separate = false;
                               9609                 :                :             }
                               9610         [ +  + ]:            562 :             else if (tbinfo->relkind == RELKIND_VIEW)
                               9611                 :                :             {
                               9612                 :                :                 /*
                               9613                 :                :                  * Defaults on a VIEW must always be dumped as separate ALTER
                               9614                 :                :                  * TABLE commands.
                               9615                 :                :                  */
                               9616                 :             38 :                 attrdefs[j].separate = true;
                               9617                 :                :             }
                               9618         [ +  + ]:            524 :             else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
                               9619                 :                :             {
                               9620                 :                :                 /* column will be suppressed, print default separately */
                               9621                 :              4 :                 attrdefs[j].separate = true;
                               9622                 :                :             }
                               9623                 :                :             else
                               9624                 :                :             {
                               9625                 :            520 :                 attrdefs[j].separate = false;
                               9626                 :                :             }
                               9627                 :                : 
                               9628         [ +  + ]:           1266 :             if (!attrdefs[j].separate)
                               9629                 :                :             {
                               9630                 :                :                 /*
                               9631                 :                :                  * Mark the default as needing to appear before the table, so
                               9632                 :                :                  * that any dependencies it has must be emitted before the
                               9633                 :                :                  * CREATE TABLE.  If this is not possible, we'll change to
                               9634                 :                :                  * "separate" mode while sorting dependencies.
                               9635                 :                :                  */
                               9636                 :           1224 :                 addObjectDependency(&tbinfo->dobj,
                               9637                 :           1224 :                                     attrdefs[j].dobj.dumpId);
                               9638                 :                :             }
                               9639                 :                : 
                               9640                 :           1266 :             tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
                               9641                 :                :         }
                               9642                 :                : 
                               9643                 :             66 :         PQclear(res);
                               9644                 :                :     }
                               9645                 :                : 
                               9646                 :                :     /*
                               9647                 :                :      * Get info about NOT NULL NOT VALID constraints.  This is skipped for a
                               9648                 :                :      * data-only dump, as it is only needed for table schemas.
                               9649                 :                :      */
  152 alvherre@alvh.no-ip.     9650   [ +  +  +  + ]:            185 :     if (dopt->dumpSchema && invalidnotnulloids)
                               9651                 :                :     {
                               9652                 :                :         ConstraintInfo *constrs;
                               9653                 :                :         int         numConstrs;
                               9654                 :                :         int         i_tableoid;
                               9655                 :                :         int         i_oid;
                               9656                 :                :         int         i_conrelid;
                               9657                 :                :         int         i_conname;
                               9658                 :                :         int         i_consrc;
                               9659                 :                :         int         i_conislocal;
                               9660                 :                : 
   82 peter@eisentraut.org     9661                 :             43 :         pg_log_info("finding invalid not-null constraints");
                               9662                 :                : 
  152 alvherre@alvh.no-ip.     9663                 :             43 :         resetPQExpBuffer(q);
                               9664                 :             43 :         appendPQExpBuffer(q,
                               9665                 :                :                           "SELECT c.tableoid, c.oid, conrelid, conname, "
                               9666                 :                :                           "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
                               9667                 :                :                           "conislocal, convalidated "
                               9668                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(conoid)\n"
                               9669                 :                :                           "JOIN pg_catalog.pg_constraint c ON (src.conoid = c.oid)\n"
                               9670                 :                :                           "ORDER BY c.conrelid, c.conname",
                               9671                 :             43 :                           invalidnotnulloids->data);
                               9672                 :                : 
                               9673                 :             43 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9674                 :                : 
                               9675                 :             43 :         numConstrs = PQntuples(res);
                               9676                 :             43 :         constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
                               9677                 :                : 
                               9678                 :             43 :         i_tableoid = PQfnumber(res, "tableoid");
                               9679                 :             43 :         i_oid = PQfnumber(res, "oid");
                               9680                 :             43 :         i_conrelid = PQfnumber(res, "conrelid");
                               9681                 :             43 :         i_conname = PQfnumber(res, "conname");
                               9682                 :             43 :         i_consrc = PQfnumber(res, "consrc");
                               9683                 :             43 :         i_conislocal = PQfnumber(res, "conislocal");
                               9684                 :                : 
                               9685                 :                :         /* As above, this loop iterates once per table, not once per row */
                               9686                 :             43 :         curtblindx = -1;
                               9687         [ +  + ]:            116 :         for (int j = 0; j < numConstrs;)
                               9688                 :                :         {
                               9689                 :             73 :             Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               9690                 :             73 :             TableInfo  *tbinfo = NULL;
                               9691                 :                :             int         numcons;
                               9692                 :                : 
                               9693                 :                :             /* Count rows for this table */
                               9694         [ +  + ]:             73 :             for (numcons = 1; numcons < numConstrs - j; numcons++)
                               9695         [ +  - ]:             30 :                 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
                               9696                 :             30 :                     break;
                               9697                 :                : 
                               9698                 :                :             /*
                               9699                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9700                 :                :              * OID order.
                               9701                 :                :              */
                               9702         [ +  - ]:          14202 :             while (++curtblindx < numTables)
                               9703                 :                :             {
                               9704                 :          14202 :                 tbinfo = &tblinfo[curtblindx];
                               9705         [ +  + ]:          14202 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               9706                 :             73 :                     break;
                               9707                 :                :             }
                               9708         [ -  + ]:             73 :             if (curtblindx >= numTables)
  152 alvherre@alvh.no-ip.     9709                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               9710                 :                : 
  152 alvherre@alvh.no-ip.     9711         [ +  + ]:CBC         146 :             for (int c = 0; c < numcons; c++, j++)
                               9712                 :                :             {
                               9713                 :             73 :                 constrs[j].dobj.objType = DO_CONSTRAINT;
                               9714                 :             73 :                 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               9715                 :             73 :                 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               9716                 :             73 :                 AssignDumpId(&constrs[j].dobj);
                               9717                 :             73 :                 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               9718                 :             73 :                 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
                               9719                 :             73 :                 constrs[j].contable = tbinfo;
                               9720                 :             73 :                 constrs[j].condomain = NULL;
                               9721                 :             73 :                 constrs[j].contype = 'n';
                               9722                 :             73 :                 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
                               9723                 :             73 :                 constrs[j].confrelid = InvalidOid;
                               9724                 :             73 :                 constrs[j].conindex = 0;
                               9725                 :             73 :                 constrs[j].condeferrable = false;
                               9726                 :             73 :                 constrs[j].condeferred = false;
                               9727                 :             73 :                 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
                               9728                 :                : 
                               9729                 :                :                 /*
                               9730                 :                :                  * All invalid not-null constraints must be dumped separately,
                               9731                 :                :                  * because CREATE TABLE would not create them as invalid, and
                               9732                 :                :                  * also because they must be created after potentially
                               9733                 :                :                  * violating data has been loaded.
                               9734                 :                :                  */
                               9735                 :             73 :                 constrs[j].separate = true;
                               9736                 :                : 
                               9737                 :             73 :                 constrs[j].dobj.dump = tbinfo->dobj.dump;
                               9738                 :                :             }
                               9739                 :                :         }
                               9740                 :             43 :         PQclear(res);
                               9741                 :                :     }
                               9742                 :                : 
                               9743                 :                :     /*
                               9744                 :                :      * Get info about table CHECK constraints.  This is skipped for a
                               9745                 :                :      * data-only dump, as it is only needed for table schemas.
                               9746                 :                :      */
  285 nathan@postgresql.or     9747   [ +  +  +  + ]:            185 :     if (dopt->dumpSchema && checkoids->len > 2)
                               9748                 :                :     {
                               9749                 :                :         ConstraintInfo *constrs;
                               9750                 :                :         int         numConstrs;
                               9751                 :                :         int         i_tableoid;
                               9752                 :                :         int         i_oid;
                               9753                 :                :         int         i_conrelid;
                               9754                 :                :         int         i_conname;
                               9755                 :                :         int         i_consrc;
                               9756                 :                :         int         i_conislocal;
                               9757                 :                :         int         i_convalidated;
                               9758                 :                : 
 1370 tgl@sss.pgh.pa.us        9759                 :             67 :         pg_log_info("finding table check constraints");
                               9760                 :                : 
                               9761                 :             67 :         resetPQExpBuffer(q);
                               9762                 :             67 :         appendPQExpBuffer(q,
                               9763                 :                :                           "SELECT c.tableoid, c.oid, conrelid, conname, "
                               9764                 :                :                           "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
                               9765                 :                :                           "conislocal, convalidated "
                               9766                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9767                 :                :                           "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               9768                 :                :                           "WHERE contype = 'c' "
                               9769                 :                :                           "ORDER BY c.conrelid, c.conname",
                               9770                 :                :                           checkoids->data);
                               9771                 :                : 
                               9772                 :             67 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9773                 :                : 
                               9774                 :             67 :         numConstrs = PQntuples(res);
                               9775                 :             67 :         constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
                               9776                 :                : 
                               9777                 :             67 :         i_tableoid = PQfnumber(res, "tableoid");
                               9778                 :             67 :         i_oid = PQfnumber(res, "oid");
                               9779                 :             67 :         i_conrelid = PQfnumber(res, "conrelid");
                               9780                 :             67 :         i_conname = PQfnumber(res, "conname");
                               9781                 :             67 :         i_consrc = PQfnumber(res, "consrc");
                               9782                 :             67 :         i_conislocal = PQfnumber(res, "conislocal");
                               9783                 :             67 :         i_convalidated = PQfnumber(res, "convalidated");
                               9784                 :                : 
                               9785                 :                :         /* As above, this loop iterates once per table, not once per row */
                               9786                 :             67 :         curtblindx = -1;
                               9787         [ +  + ]:            602 :         for (int j = 0; j < numConstrs;)
                               9788                 :                :         {
                               9789                 :            535 :             Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               9790                 :            535 :             TableInfo  *tbinfo = NULL;
                               9791                 :                :             int         numcons;
                               9792                 :                : 
                               9793                 :                :             /* Count rows for this table */
                               9794         [ +  + ]:            682 :             for (numcons = 1; numcons < numConstrs - j; numcons++)
                               9795         [ +  + ]:            615 :                 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
                               9796                 :            468 :                     break;
                               9797                 :                : 
                               9798                 :                :             /*
                               9799                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9800                 :                :              * OID order.
                               9801                 :                :              */
                               9802         [ +  - ]:          19592 :             while (++curtblindx < numTables)
                               9803                 :                :             {
                               9804                 :          19592 :                 tbinfo = &tblinfo[curtblindx];
                               9805         [ +  + ]:          19592 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               9806                 :            535 :                     break;
                               9807                 :                :             }
                               9808         [ -  + ]:            535 :             if (curtblindx >= numTables)
 1247 tgl@sss.pgh.pa.us        9809                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               9810                 :                : 
 1370 tgl@sss.pgh.pa.us        9811         [ -  + ]:CBC         535 :             if (numcons != tbinfo->ncheck)
                               9812                 :                :             {
 2350 peter@eisentraut.org     9813                 :UBC           0 :                 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
                               9814                 :                :                                       "expected %d check constraints on table \"%s\" but found %d",
                               9815                 :                :                                       tbinfo->ncheck),
                               9816                 :                :                              tbinfo->ncheck, tbinfo->dobj.name, numcons);
 1247 tgl@sss.pgh.pa.us        9817                 :              0 :                 pg_log_error_hint("The system catalogs might be corrupted.");
 4951 rhaas@postgresql.org     9818                 :              0 :                 exit_nicely(1);
                               9819                 :                :             }
                               9820                 :                : 
 1370 tgl@sss.pgh.pa.us        9821                 :CBC         535 :             tbinfo->checkexprs = constrs + j;
                               9822                 :                : 
                               9823         [ +  + ]:           1217 :             for (int c = 0; c < numcons; c++, j++)
                               9824                 :                :             {
                               9825                 :            682 :                 bool        validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
                               9826                 :                : 
 7945                          9827                 :            682 :                 constrs[j].dobj.objType = DO_CONSTRAINT;
 1370                          9828                 :            682 :                 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               9829                 :            682 :                 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
 7945                          9830                 :            682 :                 AssignDumpId(&constrs[j].dobj);
 1370                          9831                 :            682 :                 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
 7857                          9832                 :            682 :                 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
 7945                          9833                 :            682 :                 constrs[j].contable = tbinfo;
                               9834                 :            682 :                 constrs[j].condomain = NULL;
                               9835                 :            682 :                 constrs[j].contype = 'c';
 1370                          9836                 :            682 :                 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
 6207                          9837                 :            682 :                 constrs[j].confrelid = InvalidOid;
 7945                          9838                 :            682 :                 constrs[j].conindex = 0;
 5883                          9839                 :            682 :                 constrs[j].condeferrable = false;
                               9840                 :            682 :                 constrs[j].condeferred = false;
 1370                          9841                 :            682 :                 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
                               9842                 :                : 
                               9843                 :                :                 /*
                               9844                 :                :                  * An unvalidated constraint needs to be dumped separately, so
                               9845                 :                :                  * that potentially-violating existing data is loaded before
                               9846                 :                :                  * the constraint.
                               9847                 :                :                  */
 4887 alvherre@alvh.no-ip.     9848                 :            682 :                 constrs[j].separate = !validated;
                               9849                 :                : 
 7128 tgl@sss.pgh.pa.us        9850                 :            682 :                 constrs[j].dobj.dump = tbinfo->dobj.dump;
                               9851                 :                : 
                               9852                 :                :                 /*
                               9853                 :                :                  * Mark the constraint as needing to appear before the table
                               9854                 :                :                  * --- this is so that any other dependencies of the
                               9855                 :                :                  * constraint will be emitted before we try to create the
                               9856                 :                :                  * table.  If the constraint is to be dumped separately, it
                               9857                 :                :                  * will be dumped after data is loaded anyway, so don't do it.
                               9858                 :                :                  * (There's an automatic dependency in the opposite direction
                               9859                 :                :                  * anyway, so don't need to add one manually here.)
                               9860                 :                :                  */
 5024 alvherre@alvh.no-ip.     9861         [ +  + ]:            682 :                 if (!constrs[j].separate)
 5035                          9862                 :            617 :                     addObjectDependency(&tbinfo->dobj,
                               9863                 :            617 :                                         constrs[j].dobj.dumpId);
                               9864                 :                : 
                               9865                 :                :                 /*
                               9866                 :                :                  * We will detect later whether the constraint must be split
                               9867                 :                :                  * out from the table definition.
                               9868                 :                :                  */
                               9869                 :                :             }
                               9870                 :                :         }
                               9871                 :                : 
 1370 tgl@sss.pgh.pa.us        9872                 :             67 :         PQclear(res);
                               9873                 :                :     }
                               9874                 :                : 
 8800                          9875                 :            185 :     destroyPQExpBuffer(q);
 1370                          9876                 :            185 :     destroyPQExpBuffer(tbloids);
                               9877                 :            185 :     destroyPQExpBuffer(checkoids);
10651 scrappy@hub.org          9878                 :            185 : }
                               9879                 :                : 
                               9880                 :                : /*
                               9881                 :                :  * Based on the getTableAttrs query's row corresponding to one column, set
                               9882                 :                :  * the name and flags to handle a not-null constraint for that column in
                               9883                 :                :  * the tbinfo struct.
                               9884                 :                :  *
                               9885                 :                :  * Result row 'r' is for tbinfo's attribute 'j'.
                               9886                 :                :  *
                               9887                 :                :  * There are four possibilities:
                               9888                 :                :  * 1) the column has no not-null constraints. In that case, ->notnull_constrs
                               9889                 :                :  *    (the constraint name) remains NULL.
                               9890                 :                :  * 2) The column has a constraint with no name (this is the case when
                               9891                 :                :  *    constraints come from pre-18 servers).  In this case, ->notnull_constrs
                               9892                 :                :  *    is set to the empty string; dumpTableSchema will print just "NOT NULL".
                               9893                 :                :  * 3) The column has an invalid not-null constraint.  This must be treated
                               9894                 :                :  *    as a separate object (because it must be created after the table data
                               9895                 :                :  *    is loaded).  So we add its OID to invalidnotnulloids for processing
                               9896                 :                :  *    elsewhere and do nothing further with it here.  We distinguish this
                               9897                 :                :  *    case because the "notnull_invalidoid" column has been set to a non-NULL
                               9898                 :                :  *    value, which is the constraint OID.  Valid constraints have a null OID.
                               9899                 :                :  * 4) The column has a constraint with a known name; in that case
                               9900                 :                :  *    notnull_constrs carries that name and dumpTableSchema will print
                               9901                 :                :  *    "CONSTRAINT the_name NOT NULL".  However, if the name is the default
                               9902                 :                :  *    (table_column_not_null) and there's no comment on the constraint,
                               9903                 :                :  *    there's no need to print that name in the dump, so notnull_constrs
                               9904                 :                :  *    is set to the empty string and it behaves as case 2.
                               9905                 :                :  *
                               9906                 :                :  * In a child table that inherits from a parent already containing NOT NULL
                               9907                 :                :  * constraints and the columns in the child don't have their own NOT NULL
                               9908                 :                :  * declarations, we suppress printing constraints in the child: the
                               9909                 :                :  * constraints are acquired at the point where the child is attached to the
                               9910                 :                :  * parent.  This is tracked in ->notnull_islocal; for servers pre-18 this is
                               9911                 :                :  * set not here but in flagInhAttrs.  That flag is also used when the
                               9912                 :                :  * constraint was validated in a child but all its parent have it as NOT
                               9913                 :                :  * VALID.
                               9914                 :                :  *
                               9915                 :                :  * Any of these constraints might have the NO INHERIT bit.  If so we set
                               9916                 :                :  * ->notnull_noinh and NO INHERIT will be printed by dumpTableSchema.
                               9917                 :                :  *
                               9918                 :                :  * In case 4 above, the name comparison is a bit of a hack; it actually fails
                               9919                 :                :  * to do the right thing in all but the trivial case.  However, the downside
                               9920                 :                :  * of getting it wrong is simply that the name is printed rather than
                               9921                 :                :  * suppressed, so it's not a big deal.
                               9922                 :                :  *
                               9923                 :                :  * invalidnotnulloids is expected to be given as NULL; if any invalid not-null
                               9924                 :                :  * constraints are found, it is initialized and filled with the array of
                               9925                 :                :  * OIDs of such constraints, for later processing.
                               9926                 :                :  */
                               9927                 :                : static void
  302 alvherre@alvh.no-ip.     9928                 :          25248 : determineNotNullFlags(Archive *fout, PGresult *res, int r,
                               9929                 :                :                       TableInfo *tbinfo, int j,
                               9930                 :                :                       int i_notnull_name,
                               9931                 :                :                       int i_notnull_comment,
                               9932                 :                :                       int i_notnull_invalidoid,
                               9933                 :                :                       int i_notnull_noinherit,
                               9934                 :                :                       int i_notnull_islocal,
                               9935                 :                :                       PQExpBuffer *invalidnotnulloids)
                               9936                 :                : {
                               9937                 :          25248 :     DumpOptions *dopt = fout->dopt;
                               9938                 :                : 
                               9939                 :                :     /*
                               9940                 :                :      * If this not-null constraint is not valid, list its OID in
                               9941                 :                :      * invalidnotnulloids and do nothing further.  It'll be processed
                               9942                 :                :      * elsewhere later.
                               9943                 :                :      *
                               9944                 :                :      * Because invalid not-null constraints are rare, we don't want to malloc
                               9945                 :                :      * invalidnotnulloids until we're sure we're going it need it, which
                               9946                 :                :      * happens here.
                               9947                 :                :      */
  152                          9948         [ +  + ]:          25248 :     if (!PQgetisnull(res, r, i_notnull_invalidoid))
                               9949                 :                :     {
                               9950                 :             79 :         char       *constroid = PQgetvalue(res, r, i_notnull_invalidoid);
                               9951                 :                : 
                               9952         [ +  + ]:             79 :         if (*invalidnotnulloids == NULL)
                               9953                 :                :         {
                               9954                 :             49 :             *invalidnotnulloids = createPQExpBuffer();
                               9955                 :             49 :             appendPQExpBufferChar(*invalidnotnulloids, '{');
  142 drowley@postgresql.o     9956                 :             49 :             appendPQExpBufferStr(*invalidnotnulloids, constroid);
                               9957                 :                :         }
                               9958                 :                :         else
  152 alvherre@alvh.no-ip.     9959                 :             30 :             appendPQExpBuffer(*invalidnotnulloids, ",%s", constroid);
                               9960                 :                : 
                               9961                 :                :         /*
                               9962                 :                :          * Track when a parent constraint is invalid for the cases where a
                               9963                 :                :          * child constraint has been validated independenly.
                               9964                 :                :          */
  131 alvherre@kurilemu.de     9965                 :             79 :         tbinfo->notnull_invalid[j] = true;
                               9966                 :                : 
                               9967                 :                :         /* nothing else to do */
  152 alvherre@alvh.no-ip.     9968                 :             79 :         tbinfo->notnull_constrs[j] = NULL;
                               9969                 :             79 :         return;
                               9970                 :                :     }
                               9971                 :                : 
                               9972                 :                :     /*
                               9973                 :                :      * notnull_noinh is straight from the query result. notnull_islocal also,
                               9974                 :                :      * though flagInhAttrs may change that one later.
                               9975                 :                :      */
  302                          9976                 :          25169 :     tbinfo->notnull_noinh[j] = PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
                               9977                 :          25169 :     tbinfo->notnull_islocal[j] = PQgetvalue(res, r, i_notnull_islocal)[0] == 't';
  131 alvherre@kurilemu.de     9978                 :          25169 :     tbinfo->notnull_invalid[j] = false;
                               9979                 :                : 
                               9980                 :                :     /*
                               9981                 :                :      * Determine a constraint name to use.  If the column is not marked not-
                               9982                 :                :      * null, we set NULL which cues ... to do nothing.  An empty string says
                               9983                 :                :      * to print an unnamed NOT NULL, and anything else is a constraint name to
                               9984                 :                :      * use.
                               9985                 :                :      */
  302 alvherre@alvh.no-ip.     9986         [ -  + ]:          25169 :     if (fout->remoteVersion < 180000)
                               9987                 :                :     {
                               9988                 :                :         /*
                               9989                 :                :          * < 18 doesn't have not-null names, so an unnamed constraint is
                               9990                 :                :          * sufficient.
                               9991                 :                :          */
  302 alvherre@alvh.no-ip.     9992         [ #  # ]:UBC           0 :         if (PQgetisnull(res, r, i_notnull_name))
                               9993                 :              0 :             tbinfo->notnull_constrs[j] = NULL;
                               9994                 :                :         else
                               9995                 :              0 :             tbinfo->notnull_constrs[j] = "";
                               9996                 :                :     }
                               9997                 :                :     else
                               9998                 :                :     {
  302 alvherre@alvh.no-ip.     9999         [ +  + ]:CBC       25169 :         if (PQgetisnull(res, r, i_notnull_name))
                              10000                 :          22417 :             tbinfo->notnull_constrs[j] = NULL;
                              10001                 :                :         else
                              10002                 :                :         {
                              10003                 :                :             /*
                              10004                 :                :              * In binary upgrade of inheritance child tables, must have a
                              10005                 :                :              * constraint name that we can UPDATE later; same if there's a
                              10006                 :                :              * comment on the constraint.
                              10007                 :                :              */
   72 alvherre@kurilemu.de    10008         [ +  + ]:           2752 :             if ((dopt->binary_upgrade &&
                              10009         [ +  + ]:            326 :                  !tbinfo->ispartition &&
                              10010   [ +  -  +  + ]:           3000 :                  !tbinfo->notnull_islocal) ||
                              10011                 :           2752 :                 !PQgetisnull(res, r, i_notnull_comment))
                              10012                 :                :             {
  302 alvherre@alvh.no-ip.    10013                 :             54 :                 tbinfo->notnull_constrs[j] =
                              10014                 :             54 :                     pstrdup(PQgetvalue(res, r, i_notnull_name));
                              10015                 :                :             }
                              10016                 :                :             else
                              10017                 :                :             {
                              10018                 :                :                 char       *default_name;
                              10019                 :                : 
                              10020                 :                :                 /* XXX should match ChooseConstraintName better */
                              10021                 :           2698 :                 default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
                              10022                 :           2698 :                                         tbinfo->attnames[j]);
                              10023         [ +  + ]:           2698 :                 if (strcmp(default_name,
                              10024                 :           2698 :                            PQgetvalue(res, r, i_notnull_name)) == 0)
                              10025                 :           1762 :                     tbinfo->notnull_constrs[j] = "";
                              10026                 :                :                 else
                              10027                 :                :                 {
                              10028                 :            936 :                     tbinfo->notnull_constrs[j] =
                              10029                 :            936 :                         pstrdup(PQgetvalue(res, r, i_notnull_name));
                              10030                 :                :                 }
  206 tgl@sss.pgh.pa.us       10031                 :           2698 :                 free(default_name);
                              10032                 :                :             }
                              10033                 :                :         }
                              10034                 :                :     }
                              10035                 :                : }
                              10036                 :                : 
                              10037                 :                : /*
                              10038                 :                :  * Test whether a column should be printed as part of table's CREATE TABLE.
                              10039                 :                :  * Column number is zero-based.
                              10040                 :                :  *
                              10041                 :                :  * Normally this is always true, but it's false for dropped columns, as well
                              10042                 :                :  * as those that were inherited without any local definition.  (If we print
                              10043                 :                :  * such a column it will mistakenly get pg_attribute.attislocal set to true.)
                              10044                 :                :  * For partitions, it's always true, because we want the partitions to be
                              10045                 :                :  * created independently and ATTACH PARTITION used afterwards.
                              10046                 :                :  *
                              10047                 :                :  * In binary_upgrade mode, we must print all columns and fix the attislocal/
                              10048                 :                :  * attisdropped state later, so as to keep control of the physical column
                              10049                 :                :  * order.
                              10050                 :                :  *
                              10051                 :                :  * This function exists because there are scattered nonobvious places that
                              10052                 :                :  * must be kept in sync with this decision.
                              10053                 :                :  */
                              10054                 :                : bool
 1669 peter@eisentraut.org    10055                 :          41146 : shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
                              10056                 :                : {
 3980 alvherre@alvh.no-ip.    10057         [ +  + ]:          41146 :     if (dopt->binary_upgrade)
 4957 tgl@sss.pgh.pa.us       10058                 :           6206 :         return true;
 2280 alvherre@alvh.no-ip.    10059         [ +  + ]:          34940 :     if (tbinfo->attisdropped[colno])
                              10060                 :            738 :         return false;
                              10061   [ +  +  +  + ]:          34202 :     return (tbinfo->attislocal[colno] || tbinfo->ispartition);
                              10062                 :                : }
                              10063                 :                : 
                              10064                 :                : 
                              10065                 :                : /*
                              10066                 :                :  * getTSParsers:
                              10067                 :                :  *    get information about all text search parsers in the system catalogs
                              10068                 :                :  */
                              10069                 :                : void
  431 nathan@postgresql.or    10070                 :            185 : getTSParsers(Archive *fout)
                              10071                 :                : {
                              10072                 :                :     PGresult   *res;
                              10073                 :                :     int         ntups;
                              10074                 :                :     int         i;
                              10075                 :                :     PQExpBuffer query;
                              10076                 :                :     TSParserInfo *prsinfo;
                              10077                 :                :     int         i_tableoid;
                              10078                 :                :     int         i_oid;
                              10079                 :                :     int         i_prsname;
                              10080                 :                :     int         i_prsnamespace;
                              10081                 :                :     int         i_prsstart;
                              10082                 :                :     int         i_prstoken;
                              10083                 :                :     int         i_prsend;
                              10084                 :                :     int         i_prsheadline;
                              10085                 :                :     int         i_prslextype;
                              10086                 :                : 
 4925 peter_e@gmx.net         10087                 :            185 :     query = createPQExpBuffer();
                              10088                 :                : 
                              10089                 :                :     /*
                              10090                 :                :      * find all text search objects, including builtin ones; we filter out
                              10091                 :                :      * system-defined objects at dump-out time.
                              10092                 :                :      */
                              10093                 :                : 
 4310 heikki.linnakangas@i    10094                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
                              10095                 :                :                          "prsstart::oid, prstoken::oid, "
                              10096                 :                :                          "prsend::oid, prsheadline::oid, prslextype::oid "
                              10097                 :                :                          "FROM pg_ts_parser");
                              10098                 :                : 
 4960 rhaas@postgresql.org    10099                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10100                 :                : 
 6591 tgl@sss.pgh.pa.us       10101                 :            185 :     ntups = PQntuples(res);
                              10102                 :                : 
 5034 bruce@momjian.us        10103                 :            185 :     prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
                              10104                 :                : 
 6591 tgl@sss.pgh.pa.us       10105                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                              10106                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10107                 :            185 :     i_prsname = PQfnumber(res, "prsname");
                              10108                 :            185 :     i_prsnamespace = PQfnumber(res, "prsnamespace");
                              10109                 :            185 :     i_prsstart = PQfnumber(res, "prsstart");
                              10110                 :            185 :     i_prstoken = PQfnumber(res, "prstoken");
                              10111                 :            185 :     i_prsend = PQfnumber(res, "prsend");
                              10112                 :            185 :     i_prsheadline = PQfnumber(res, "prsheadline");
                              10113                 :            185 :     i_prslextype = PQfnumber(res, "prslextype");
                              10114                 :                : 
                              10115         [ +  + ]:            421 :     for (i = 0; i < ntups; i++)
                              10116                 :                :     {
                              10117                 :            236 :         prsinfo[i].dobj.objType = DO_TSPARSER;
                              10118                 :            236 :         prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10119                 :            236 :         prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10120                 :            236 :         AssignDumpId(&prsinfo[i].dobj);
 5034 bruce@momjian.us        10121                 :            236 :         prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
 4961 rhaas@postgresql.org    10122                 :            472 :         prsinfo[i].dobj.namespace =
 1838 peter@eisentraut.org    10123                 :            236 :             findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
 6591 tgl@sss.pgh.pa.us       10124                 :            236 :         prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
                              10125                 :            236 :         prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
                              10126                 :            236 :         prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
                              10127                 :            236 :         prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
                              10128                 :            236 :         prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
                              10129                 :                : 
                              10130                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10131                 :            236 :         selectDumpableObject(&(prsinfo[i].dobj), fout);
                              10132                 :                :     }
                              10133                 :                : 
 6591 tgl@sss.pgh.pa.us       10134                 :            185 :     PQclear(res);
                              10135                 :                : 
                              10136                 :            185 :     destroyPQExpBuffer(query);
                              10137                 :            185 : }
                              10138                 :                : 
                              10139                 :                : /*
                              10140                 :                :  * getTSDictionaries:
                              10141                 :                :  *    get information about all text search dictionaries in the system catalogs
                              10142                 :                :  */
                              10143                 :                : void
  431 nathan@postgresql.or    10144                 :            185 : getTSDictionaries(Archive *fout)
                              10145                 :                : {
                              10146                 :                :     PGresult   *res;
                              10147                 :                :     int         ntups;
                              10148                 :                :     int         i;
                              10149                 :                :     PQExpBuffer query;
                              10150                 :                :     TSDictInfo *dictinfo;
                              10151                 :                :     int         i_tableoid;
                              10152                 :                :     int         i_oid;
                              10153                 :                :     int         i_dictname;
                              10154                 :                :     int         i_dictnamespace;
                              10155                 :                :     int         i_dictowner;
                              10156                 :                :     int         i_dicttemplate;
                              10157                 :                :     int         i_dictinitoption;
                              10158                 :                : 
 4925 peter_e@gmx.net         10159                 :            185 :     query = createPQExpBuffer();
                              10160                 :                : 
 1096 drowley@postgresql.o    10161                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
                              10162                 :                :                          "dictnamespace, dictowner, "
                              10163                 :                :                          "dicttemplate, dictinitoption "
                              10164                 :                :                          "FROM pg_ts_dict");
                              10165                 :                : 
 4960 rhaas@postgresql.org    10166                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10167                 :                : 
 6591 tgl@sss.pgh.pa.us       10168                 :            185 :     ntups = PQntuples(res);
                              10169                 :                : 
 5034 bruce@momjian.us        10170                 :            185 :     dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
                              10171                 :                : 
 6591 tgl@sss.pgh.pa.us       10172                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                              10173                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10174                 :            185 :     i_dictname = PQfnumber(res, "dictname");
                              10175                 :            185 :     i_dictnamespace = PQfnumber(res, "dictnamespace");
 1345                         10176                 :            185 :     i_dictowner = PQfnumber(res, "dictowner");
 6591                         10177                 :            185 :     i_dictinitoption = PQfnumber(res, "dictinitoption");
                              10178                 :            185 :     i_dicttemplate = PQfnumber(res, "dicttemplate");
                              10179                 :                : 
                              10180         [ +  + ]:           5849 :     for (i = 0; i < ntups; i++)
                              10181                 :                :     {
                              10182                 :           5664 :         dictinfo[i].dobj.objType = DO_TSDICT;
                              10183                 :           5664 :         dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10184                 :           5664 :         dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10185                 :           5664 :         AssignDumpId(&dictinfo[i].dobj);
 5034 bruce@momjian.us        10186                 :           5664 :         dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
 4961 rhaas@postgresql.org    10187                 :          11328 :         dictinfo[i].dobj.namespace =
 1838 peter@eisentraut.org    10188                 :           5664 :             findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
 1345 tgl@sss.pgh.pa.us       10189                 :           5664 :         dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
 6591                         10190                 :           5664 :         dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
                              10191         [ +  + ]:           5664 :         if (PQgetisnull(res, i, i_dictinitoption))
                              10192                 :            236 :             dictinfo[i].dictinitoption = NULL;
                              10193                 :                :         else
 5034 bruce@momjian.us        10194                 :           5428 :             dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
                              10195                 :                : 
                              10196                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10197                 :           5664 :         selectDumpableObject(&(dictinfo[i].dobj), fout);
                              10198                 :                :     }
                              10199                 :                : 
 6591 tgl@sss.pgh.pa.us       10200                 :            185 :     PQclear(res);
                              10201                 :                : 
                              10202                 :            185 :     destroyPQExpBuffer(query);
                              10203                 :            185 : }
                              10204                 :                : 
                              10205                 :                : /*
                              10206                 :                :  * getTSTemplates:
                              10207                 :                :  *    get information about all text search templates in the system catalogs
                              10208                 :                :  */
                              10209                 :                : void
  431 nathan@postgresql.or    10210                 :            185 : getTSTemplates(Archive *fout)
                              10211                 :                : {
                              10212                 :                :     PGresult   *res;
                              10213                 :                :     int         ntups;
                              10214                 :                :     int         i;
                              10215                 :                :     PQExpBuffer query;
                              10216                 :                :     TSTemplateInfo *tmplinfo;
                              10217                 :                :     int         i_tableoid;
                              10218                 :                :     int         i_oid;
                              10219                 :                :     int         i_tmplname;
                              10220                 :                :     int         i_tmplnamespace;
                              10221                 :                :     int         i_tmplinit;
                              10222                 :                :     int         i_tmpllexize;
                              10223                 :                : 
 4925 peter_e@gmx.net         10224                 :            185 :     query = createPQExpBuffer();
                              10225                 :                : 
 4310 heikki.linnakangas@i    10226                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
                              10227                 :                :                          "tmplnamespace, tmplinit::oid, tmpllexize::oid "
                              10228                 :                :                          "FROM pg_ts_template");
                              10229                 :                : 
 4960 rhaas@postgresql.org    10230                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10231                 :                : 
 6591 tgl@sss.pgh.pa.us       10232                 :            185 :     ntups = PQntuples(res);
                              10233                 :                : 
 5034 bruce@momjian.us        10234                 :            185 :     tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
                              10235                 :                : 
 6591 tgl@sss.pgh.pa.us       10236                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                              10237                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10238                 :            185 :     i_tmplname = PQfnumber(res, "tmplname");
                              10239                 :            185 :     i_tmplnamespace = PQfnumber(res, "tmplnamespace");
                              10240                 :            185 :     i_tmplinit = PQfnumber(res, "tmplinit");
                              10241                 :            185 :     i_tmpllexize = PQfnumber(res, "tmpllexize");
                              10242                 :                : 
                              10243         [ +  + ]:           1161 :     for (i = 0; i < ntups; i++)
                              10244                 :                :     {
                              10245                 :            976 :         tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
                              10246                 :            976 :         tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10247                 :            976 :         tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10248                 :            976 :         AssignDumpId(&tmplinfo[i].dobj);
 5034 bruce@momjian.us        10249                 :            976 :         tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
 4961 rhaas@postgresql.org    10250                 :           1952 :         tmplinfo[i].dobj.namespace =
 1838 peter@eisentraut.org    10251                 :            976 :             findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
 6591 tgl@sss.pgh.pa.us       10252                 :            976 :         tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
                              10253                 :            976 :         tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
                              10254                 :                : 
                              10255                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10256                 :            976 :         selectDumpableObject(&(tmplinfo[i].dobj), fout);
                              10257                 :                :     }
                              10258                 :                : 
 6591 tgl@sss.pgh.pa.us       10259                 :            185 :     PQclear(res);
                              10260                 :                : 
                              10261                 :            185 :     destroyPQExpBuffer(query);
                              10262                 :            185 : }
                              10263                 :                : 
                              10264                 :                : /*
                              10265                 :                :  * getTSConfigurations:
                              10266                 :                :  *    get information about all text search configurations
                              10267                 :                :  */
                              10268                 :                : void
  431 nathan@postgresql.or    10269                 :            185 : getTSConfigurations(Archive *fout)
                              10270                 :                : {
                              10271                 :                :     PGresult   *res;
                              10272                 :                :     int         ntups;
                              10273                 :                :     int         i;
                              10274                 :                :     PQExpBuffer query;
                              10275                 :                :     TSConfigInfo *cfginfo;
                              10276                 :                :     int         i_tableoid;
                              10277                 :                :     int         i_oid;
                              10278                 :                :     int         i_cfgname;
                              10279                 :                :     int         i_cfgnamespace;
                              10280                 :                :     int         i_cfgowner;
                              10281                 :                :     int         i_cfgparser;
                              10282                 :                : 
 4925 peter_e@gmx.net         10283                 :            185 :     query = createPQExpBuffer();
                              10284                 :                : 
 1096 drowley@postgresql.o    10285                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
                              10286                 :                :                          "cfgnamespace, cfgowner, cfgparser "
                              10287                 :                :                          "FROM pg_ts_config");
                              10288                 :                : 
 4960 rhaas@postgresql.org    10289                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10290                 :                : 
 6591 tgl@sss.pgh.pa.us       10291                 :            185 :     ntups = PQntuples(res);
                              10292                 :                : 
 5034 bruce@momjian.us        10293                 :            185 :     cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
                              10294                 :                : 
 6591 tgl@sss.pgh.pa.us       10295                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                              10296                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10297                 :            185 :     i_cfgname = PQfnumber(res, "cfgname");
                              10298                 :            185 :     i_cfgnamespace = PQfnumber(res, "cfgnamespace");
 1345                         10299                 :            185 :     i_cfgowner = PQfnumber(res, "cfgowner");
 6591                         10300                 :            185 :     i_cfgparser = PQfnumber(res, "cfgparser");
                              10301                 :                : 
                              10302         [ +  + ]:           5814 :     for (i = 0; i < ntups; i++)
                              10303                 :                :     {
                              10304                 :           5629 :         cfginfo[i].dobj.objType = DO_TSCONFIG;
                              10305                 :           5629 :         cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10306                 :           5629 :         cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10307                 :           5629 :         AssignDumpId(&cfginfo[i].dobj);
 5034 bruce@momjian.us        10308                 :           5629 :         cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
 4961 rhaas@postgresql.org    10309                 :          11258 :         cfginfo[i].dobj.namespace =
 1838 peter@eisentraut.org    10310                 :           5629 :             findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
 1345 tgl@sss.pgh.pa.us       10311                 :           5629 :         cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
 6591                         10312                 :           5629 :         cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
                              10313                 :                : 
                              10314                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10315                 :           5629 :         selectDumpableObject(&(cfginfo[i].dobj), fout);
                              10316                 :                :     }
                              10317                 :                : 
 6591 tgl@sss.pgh.pa.us       10318                 :            185 :     PQclear(res);
                              10319                 :                : 
                              10320                 :            185 :     destroyPQExpBuffer(query);
                              10321                 :            185 : }
                              10322                 :                : 
                              10323                 :                : /*
                              10324                 :                :  * getForeignDataWrappers:
                              10325                 :                :  *    get information about all foreign-data wrappers in the system catalogs
                              10326                 :                :  */
                              10327                 :                : void
  431 nathan@postgresql.or    10328                 :            185 : getForeignDataWrappers(Archive *fout)
                              10329                 :                : {
                              10330                 :                :     PGresult   *res;
                              10331                 :                :     int         ntups;
                              10332                 :                :     int         i;
                              10333                 :                :     PQExpBuffer query;
                              10334                 :                :     FdwInfo    *fdwinfo;
                              10335                 :                :     int         i_tableoid;
                              10336                 :                :     int         i_oid;
                              10337                 :                :     int         i_fdwname;
                              10338                 :                :     int         i_fdwowner;
                              10339                 :                :     int         i_fdwhandler;
                              10340                 :                :     int         i_fdwvalidator;
                              10341                 :                :     int         i_fdwacl;
                              10342                 :                :     int         i_acldefault;
                              10343                 :                :     int         i_fdwoptions;
                              10344                 :                : 
 4228 sfrost@snowman.net      10345                 :            185 :     query = createPQExpBuffer();
                              10346                 :                : 
 1096 drowley@postgresql.o    10347                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
                              10348                 :                :                          "fdwowner, "
                              10349                 :                :                          "fdwhandler::pg_catalog.regproc, "
                              10350                 :                :                          "fdwvalidator::pg_catalog.regproc, "
                              10351                 :                :                          "fdwacl, "
                              10352                 :                :                          "acldefault('F', fdwowner) AS acldefault, "
                              10353                 :                :                          "array_to_string(ARRAY("
                              10354                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                              10355                 :                :                          "quote_literal(option_value) "
                              10356                 :                :                          "FROM pg_options_to_table(fdwoptions) "
                              10357                 :                :                          "ORDER BY option_name"
                              10358                 :                :                          "), E',\n    ') AS fdwoptions "
                              10359                 :                :                          "FROM pg_foreign_data_wrapper");
                              10360                 :                : 
 4960 rhaas@postgresql.org    10361                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10362                 :                : 
 6105 peter_e@gmx.net         10363                 :            185 :     ntups = PQntuples(res);
                              10364                 :                : 
 5034 bruce@momjian.us        10365                 :            185 :     fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
                              10366                 :                : 
 5462 heikki.linnakangas@i    10367                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 6105 peter_e@gmx.net         10368                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10369                 :            185 :     i_fdwname = PQfnumber(res, "fdwname");
 1345 tgl@sss.pgh.pa.us       10370                 :            185 :     i_fdwowner = PQfnumber(res, "fdwowner");
 5313                         10371                 :            185 :     i_fdwhandler = PQfnumber(res, "fdwhandler");
 6038 peter_e@gmx.net         10372                 :            185 :     i_fdwvalidator = PQfnumber(res, "fdwvalidator");
 6105                         10373                 :            185 :     i_fdwacl = PQfnumber(res, "fdwacl");
 1370 tgl@sss.pgh.pa.us       10374                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
 6105 peter_e@gmx.net         10375                 :            185 :     i_fdwoptions = PQfnumber(res, "fdwoptions");
                              10376                 :                : 
                              10377         [ +  + ]:            262 :     for (i = 0; i < ntups; i++)
                              10378                 :                :     {
                              10379                 :             77 :         fdwinfo[i].dobj.objType = DO_FDW;
 5462 heikki.linnakangas@i    10380                 :             77 :         fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 6105 peter_e@gmx.net         10381                 :             77 :         fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10382                 :             77 :         AssignDumpId(&fdwinfo[i].dobj);
 5034 bruce@momjian.us        10383                 :             77 :         fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
 6105 peter_e@gmx.net         10384                 :             77 :         fdwinfo[i].dobj.namespace = NULL;
 1370 tgl@sss.pgh.pa.us       10385                 :             77 :         fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
                              10386                 :             77 :         fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10387                 :             77 :         fdwinfo[i].dacl.privtype = 0;
                              10388                 :             77 :         fdwinfo[i].dacl.initprivs = NULL;
 1345                         10389                 :             77 :         fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
 5034 bruce@momjian.us        10390                 :             77 :         fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
                              10391                 :             77 :         fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
                              10392                 :             77 :         fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
                              10393                 :                : 
                              10394                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10395                 :             77 :         selectDumpableObject(&(fdwinfo[i].dobj), fout);
                              10396                 :                : 
                              10397                 :                :         /* Mark whether FDW has an ACL */
 1370 tgl@sss.pgh.pa.us       10398         [ +  + ]:             77 :         if (!PQgetisnull(res, i, i_fdwacl))
                              10399                 :             51 :             fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10400                 :                :     }
                              10401                 :                : 
 6105 peter_e@gmx.net         10402                 :            185 :     PQclear(res);
                              10403                 :                : 
                              10404                 :            185 :     destroyPQExpBuffer(query);
                              10405                 :            185 : }
                              10406                 :                : 
                              10407                 :                : /*
                              10408                 :                :  * getForeignServers:
                              10409                 :                :  *    get information about all foreign servers in the system catalogs
                              10410                 :                :  */
                              10411                 :                : void
  431 nathan@postgresql.or    10412                 :            185 : getForeignServers(Archive *fout)
                              10413                 :                : {
                              10414                 :                :     PGresult   *res;
                              10415                 :                :     int         ntups;
                              10416                 :                :     int         i;
                              10417                 :                :     PQExpBuffer query;
                              10418                 :                :     ForeignServerInfo *srvinfo;
                              10419                 :                :     int         i_tableoid;
                              10420                 :                :     int         i_oid;
                              10421                 :                :     int         i_srvname;
                              10422                 :                :     int         i_srvowner;
                              10423                 :                :     int         i_srvfdw;
                              10424                 :                :     int         i_srvtype;
                              10425                 :                :     int         i_srvversion;
                              10426                 :                :     int         i_srvacl;
                              10427                 :                :     int         i_acldefault;
                              10428                 :                :     int         i_srvoptions;
                              10429                 :                : 
 4228 sfrost@snowman.net      10430                 :            185 :     query = createPQExpBuffer();
                              10431                 :                : 
 1096 drowley@postgresql.o    10432                 :            185 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
                              10433                 :                :                          "srvowner, "
                              10434                 :                :                          "srvfdw, srvtype, srvversion, srvacl, "
                              10435                 :                :                          "acldefault('S', srvowner) AS acldefault, "
                              10436                 :                :                          "array_to_string(ARRAY("
                              10437                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                              10438                 :                :                          "quote_literal(option_value) "
                              10439                 :                :                          "FROM pg_options_to_table(srvoptions) "
                              10440                 :                :                          "ORDER BY option_name"
                              10441                 :                :                          "), E',\n    ') AS srvoptions "
                              10442                 :                :                          "FROM pg_foreign_server");
                              10443                 :                : 
 4960 rhaas@postgresql.org    10444                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10445                 :                : 
 6105 peter_e@gmx.net         10446                 :            185 :     ntups = PQntuples(res);
                              10447                 :                : 
 5034 bruce@momjian.us        10448                 :            185 :     srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
                              10449                 :                : 
 5462 heikki.linnakangas@i    10450                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
 6105 peter_e@gmx.net         10451                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10452                 :            185 :     i_srvname = PQfnumber(res, "srvname");
 1345 tgl@sss.pgh.pa.us       10453                 :            185 :     i_srvowner = PQfnumber(res, "srvowner");
 6105 peter_e@gmx.net         10454                 :            185 :     i_srvfdw = PQfnumber(res, "srvfdw");
                              10455                 :            185 :     i_srvtype = PQfnumber(res, "srvtype");
                              10456                 :            185 :     i_srvversion = PQfnumber(res, "srvversion");
                              10457                 :            185 :     i_srvacl = PQfnumber(res, "srvacl");
 1370 tgl@sss.pgh.pa.us       10458                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
 6105 peter_e@gmx.net         10459                 :            185 :     i_srvoptions = PQfnumber(res, "srvoptions");
                              10460                 :                : 
                              10461         [ +  + ]:            266 :     for (i = 0; i < ntups; i++)
                              10462                 :                :     {
                              10463                 :             81 :         srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
 5462 heikki.linnakangas@i    10464                 :             81 :         srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 6105 peter_e@gmx.net         10465                 :             81 :         srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10466                 :             81 :         AssignDumpId(&srvinfo[i].dobj);
 5034 bruce@momjian.us        10467                 :             81 :         srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
 6105 peter_e@gmx.net         10468                 :             81 :         srvinfo[i].dobj.namespace = NULL;
 1370 tgl@sss.pgh.pa.us       10469                 :             81 :         srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
                              10470                 :             81 :         srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10471                 :             81 :         srvinfo[i].dacl.privtype = 0;
                              10472                 :             81 :         srvinfo[i].dacl.initprivs = NULL;
 1345                         10473                 :             81 :         srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
 6105 peter_e@gmx.net         10474                 :             81 :         srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
 5034 bruce@momjian.us        10475                 :             81 :         srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
                              10476                 :             81 :         srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
                              10477                 :             81 :         srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
                              10478                 :                : 
                              10479                 :                :         /* Decide whether we want to dump it */
 3440 sfrost@snowman.net      10480                 :             81 :         selectDumpableObject(&(srvinfo[i].dobj), fout);
                              10481                 :                : 
                              10482                 :                :         /* Servers have user mappings */
 1370 tgl@sss.pgh.pa.us       10483                 :             81 :         srvinfo[i].dobj.components |= DUMP_COMPONENT_USERMAP;
                              10484                 :                : 
                              10485                 :                :         /* Mark whether server has an ACL */
                              10486         [ +  + ]:             81 :         if (!PQgetisnull(res, i, i_srvacl))
                              10487                 :             51 :             srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10488                 :                :     }
                              10489                 :                : 
 6105 peter_e@gmx.net         10490                 :            185 :     PQclear(res);
                              10491                 :                : 
                              10492                 :            185 :     destroyPQExpBuffer(query);
                              10493                 :            185 : }
                              10494                 :                : 
                              10495                 :                : /*
                              10496                 :                :  * getDefaultACLs:
                              10497                 :                :  *    get information about all default ACL information in the system catalogs
                              10498                 :                :  */
                              10499                 :                : void
  431 nathan@postgresql.or    10500                 :            185 : getDefaultACLs(Archive *fout)
                              10501                 :                : {
 3524 tgl@sss.pgh.pa.us       10502                 :            185 :     DumpOptions *dopt = fout->dopt;
                              10503                 :                :     DefaultACLInfo *daclinfo;
                              10504                 :                :     PQExpBuffer query;
                              10505                 :                :     PGresult   *res;
                              10506                 :                :     int         i_oid;
                              10507                 :                :     int         i_tableoid;
                              10508                 :                :     int         i_defaclrole;
                              10509                 :                :     int         i_defaclnamespace;
                              10510                 :                :     int         i_defaclobjtype;
                              10511                 :                :     int         i_defaclacl;
                              10512                 :                :     int         i_acldefault;
                              10513                 :                :     int         i,
                              10514                 :                :                 ntups;
                              10515                 :                : 
 5815                         10516                 :            185 :     query = createPQExpBuffer();
                              10517                 :                : 
                              10518                 :                :     /*
                              10519                 :                :      * Global entries (with defaclnamespace=0) replace the hard-wired default
                              10520                 :                :      * ACL for their object type.  We should dump them as deltas from the
                              10521                 :                :      * default ACL, since that will be used as a starting point for
                              10522                 :                :      * interpreting the ALTER DEFAULT PRIVILEGES commands.  On the other hand,
                              10523                 :                :      * non-global entries can only add privileges not revoke them.  We must
                              10524                 :                :      * dump those as-is (i.e., as deltas from an empty ACL).
                              10525                 :                :      *
                              10526                 :                :      * We can use defaclobjtype as the object type for acldefault(), except
                              10527                 :                :      * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
                              10528                 :                :      * 's'.
                              10529                 :                :      */
 1096 drowley@postgresql.o    10530                 :            185 :     appendPQExpBufferStr(query,
                              10531                 :                :                          "SELECT oid, tableoid, "
                              10532                 :                :                          "defaclrole, "
                              10533                 :                :                          "defaclnamespace, "
                              10534                 :                :                          "defaclobjtype, "
                              10535                 :                :                          "defaclacl, "
                              10536                 :                :                          "CASE WHEN defaclnamespace = 0 THEN "
                              10537                 :                :                          "acldefault(CASE WHEN defaclobjtype = 'S' "
                              10538                 :                :                          "THEN 's'::\"char\" ELSE defaclobjtype END, "
                              10539                 :                :                          "defaclrole) ELSE '{}' END AS acldefault "
                              10540                 :                :                          "FROM pg_default_acl");
                              10541                 :                : 
 4960 rhaas@postgresql.org    10542                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10543                 :                : 
 5815 tgl@sss.pgh.pa.us       10544                 :            185 :     ntups = PQntuples(res);
                              10545                 :                : 
 5034 bruce@momjian.us        10546                 :            185 :     daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
                              10547                 :                : 
 5815 tgl@sss.pgh.pa.us       10548                 :            185 :     i_oid = PQfnumber(res, "oid");
                              10549                 :            185 :     i_tableoid = PQfnumber(res, "tableoid");
                              10550                 :            185 :     i_defaclrole = PQfnumber(res, "defaclrole");
                              10551                 :            185 :     i_defaclnamespace = PQfnumber(res, "defaclnamespace");
                              10552                 :            185 :     i_defaclobjtype = PQfnumber(res, "defaclobjtype");
                              10553                 :            185 :     i_defaclacl = PQfnumber(res, "defaclacl");
 1370                         10554                 :            185 :     i_acldefault = PQfnumber(res, "acldefault");
                              10555                 :                : 
 5815                         10556         [ +  + ]:            403 :     for (i = 0; i < ntups; i++)
                              10557                 :                :     {
 5671 bruce@momjian.us        10558                 :            218 :         Oid         nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
                              10559                 :                : 
 5815 tgl@sss.pgh.pa.us       10560                 :            218 :         daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
                              10561                 :            218 :         daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                              10562                 :            218 :         daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                              10563                 :            218 :         AssignDumpId(&daclinfo[i].dobj);
                              10564                 :                :         /* cheesy ... is it worth coming up with a better object name? */
 5034 bruce@momjian.us        10565                 :            218 :         daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
                              10566                 :                : 
 5815 tgl@sss.pgh.pa.us       10567         [ +  + ]:            218 :         if (nspid != InvalidOid)
 1838 peter@eisentraut.org    10568                 :            102 :             daclinfo[i].dobj.namespace = findNamespace(nspid);
                              10569                 :                :         else
 5815 tgl@sss.pgh.pa.us       10570                 :            116 :             daclinfo[i].dobj.namespace = NULL;
                              10571                 :                : 
 1370                         10572                 :            218 :         daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
                              10573                 :            218 :         daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                              10574                 :            218 :         daclinfo[i].dacl.privtype = 0;
                              10575                 :            218 :         daclinfo[i].dacl.initprivs = NULL;
 1345                         10576                 :            218 :         daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
 5815                         10577                 :            218 :         daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
                              10578                 :                : 
                              10579                 :                :         /* Default ACLs are ACLs, of course */
 1370                         10580                 :            218 :         daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                              10581                 :                : 
                              10582                 :                :         /* Decide whether we want to dump it */
 3524                         10583                 :            218 :         selectDumpableDefaultACL(&(daclinfo[i]), dopt);
                              10584                 :                :     }
                              10585                 :                : 
 5815                         10586                 :            185 :     PQclear(res);
                              10587                 :                : 
                              10588                 :            185 :     destroyPQExpBuffer(query);
                              10589                 :            185 : }
                              10590                 :                : 
                              10591                 :                : /*
                              10592                 :                :  * getRoleName -- look up the name of a role, given its OID
                              10593                 :                :  *
                              10594                 :                :  * In current usage, we don't expect failures, so error out for a bad OID.
                              10595                 :                :  */
                              10596                 :                : static const char *
 1345                         10597                 :         716199 : getRoleName(const char *roleoid_str)
                              10598                 :                : {
                              10599                 :         716199 :     Oid         roleoid = atooid(roleoid_str);
                              10600                 :                : 
                              10601                 :                :     /*
                              10602                 :                :      * Do binary search to find the appropriate item.
                              10603                 :                :      */
                              10604         [ +  - ]:         716199 :     if (nrolenames > 0)
                              10605                 :                :     {
                              10606                 :         716199 :         RoleNameItem *low = &rolenames[0];
                              10607                 :         716199 :         RoleNameItem *high = &rolenames[nrolenames - 1];
                              10608                 :                : 
                              10609         [ +  - ]:        2864502 :         while (low <= high)
                              10610                 :                :         {
                              10611                 :        2864502 :             RoleNameItem *middle = low + (high - low) / 2;
                              10612                 :                : 
                              10613         [ +  + ]:        2864502 :             if (roleoid < middle->roleoid)
                              10614                 :        2147357 :                 high = middle - 1;
                              10615         [ +  + ]:         717145 :             else if (roleoid > middle->roleoid)
                              10616                 :            946 :                 low = middle + 1;
                              10617                 :                :             else
                              10618                 :         716199 :                 return middle->rolename; /* found a match */
                              10619                 :                :         }
                              10620                 :                :     }
                              10621                 :                : 
 1247 tgl@sss.pgh.pa.us       10622                 :UBC           0 :     pg_fatal("role with OID %u does not exist", roleoid);
                              10623                 :                :     return NULL;                /* keep compiler quiet */
                              10624                 :                : }
                              10625                 :                : 
                              10626                 :                : /*
                              10627                 :                :  * collectRoleNames --
                              10628                 :                :  *
                              10629                 :                :  * Construct a table of all known roles.
                              10630                 :                :  * The table is sorted by OID for speed in lookup.
                              10631                 :                :  */
                              10632                 :                : static void
 1345 tgl@sss.pgh.pa.us       10633                 :CBC         186 : collectRoleNames(Archive *fout)
                              10634                 :                : {
                              10635                 :                :     PGresult   *res;
                              10636                 :                :     const char *query;
                              10637                 :                :     int         i;
                              10638                 :                : 
                              10639                 :            186 :     query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
                              10640                 :                : 
                              10641                 :            186 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                              10642                 :                : 
                              10643                 :            186 :     nrolenames = PQntuples(res);
                              10644                 :                : 
                              10645                 :            186 :     rolenames = (RoleNameItem *) pg_malloc(nrolenames * sizeof(RoleNameItem));
                              10646                 :                : 
                              10647         [ +  + ]:           3631 :     for (i = 0; i < nrolenames; i++)
                              10648                 :                :     {
                              10649                 :           3445 :         rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
                              10650                 :           3445 :         rolenames[i].rolename = pg_strdup(PQgetvalue(res, i, 1));
                              10651                 :                :     }
                              10652                 :                : 
                              10653                 :            186 :     PQclear(res);
                              10654                 :            186 : }
                              10655                 :                : 
                              10656                 :                : /*
                              10657                 :                :  * getAdditionalACLs
                              10658                 :                :  *
                              10659                 :                :  * We have now created all the DumpableObjects, and collected the ACL data
                              10660                 :                :  * that appears in the directly-associated catalog entries.  However, there's
                              10661                 :                :  * more ACL-related info to collect.  If any of a table's columns have ACLs,
                              10662                 :                :  * we must set the TableInfo's DUMP_COMPONENT_ACL components flag, as well as
                              10663                 :                :  * its hascolumnACLs flag (we won't store the ACLs themselves here, though).
                              10664                 :                :  * Also, in versions having the pg_init_privs catalog, read that and load the
                              10665                 :                :  * information into the relevant DumpableObjects.
                              10666                 :                :  */
                              10667                 :                : static void
 1370                         10668                 :            183 : getAdditionalACLs(Archive *fout)
                              10669                 :                : {
                              10670                 :            183 :     PQExpBuffer query = createPQExpBuffer();
                              10671                 :                :     PGresult   *res;
                              10672                 :                :     int         ntups,
                              10673                 :                :                 i;
                              10674                 :                : 
                              10675                 :                :     /* Check for per-column ACLs */
 1362                         10676                 :            183 :     appendPQExpBufferStr(query,
                              10677                 :                :                          "SELECT DISTINCT attrelid FROM pg_attribute "
                              10678                 :                :                          "WHERE attacl IS NOT NULL");
                              10679                 :                : 
                              10680                 :            183 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10681                 :                : 
                              10682                 :            183 :     ntups = PQntuples(res);
                              10683         [ +  + ]:            554 :     for (i = 0; i < ntups; i++)
                              10684                 :                :     {
                              10685                 :            371 :         Oid         relid = atooid(PQgetvalue(res, i, 0));
                              10686                 :                :         TableInfo  *tblinfo;
                              10687                 :                : 
                              10688                 :            371 :         tblinfo = findTableByOid(relid);
                              10689                 :                :         /* OK to ignore tables we haven't got a DumpableObject for */
                              10690         [ +  - ]:            371 :         if (tblinfo)
                              10691                 :                :         {
                              10692                 :            371 :             tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
                              10693                 :            371 :             tblinfo->hascolumnACLs = true;
                              10694                 :                :         }
                              10695                 :                :     }
                              10696                 :            183 :     PQclear(res);
                              10697                 :                : 
                              10698                 :                :     /* Fetch initial-privileges data */
 1370                         10699         [ +  - ]:            183 :     if (fout->remoteVersion >= 90600)
                              10700                 :                :     {
                              10701                 :            183 :         printfPQExpBuffer(query,
                              10702                 :                :                           "SELECT objoid, classoid, objsubid, privtype, initprivs "
                              10703                 :                :                           "FROM pg_init_privs");
                              10704                 :                : 
                              10705                 :            183 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10706                 :                : 
                              10707                 :            183 :         ntups = PQntuples(res);
                              10708         [ +  + ]:          43313 :         for (i = 0; i < ntups; i++)
                              10709                 :                :         {
                              10710                 :          43130 :             Oid         objoid = atooid(PQgetvalue(res, i, 0));
                              10711                 :          43130 :             Oid         classoid = atooid(PQgetvalue(res, i, 1));
                              10712                 :          43130 :             int         objsubid = atoi(PQgetvalue(res, i, 2));
                              10713                 :          43130 :             char        privtype = *(PQgetvalue(res, i, 3));
                              10714                 :          43130 :             char       *initprivs = PQgetvalue(res, i, 4);
                              10715                 :                :             CatalogId   objId;
                              10716                 :                :             DumpableObject *dobj;
                              10717                 :                : 
                              10718                 :          43130 :             objId.tableoid = classoid;
                              10719                 :          43130 :             objId.oid = objoid;
                              10720                 :          43130 :             dobj = findObjectByCatalogId(objId);
                              10721                 :                :             /* OK to ignore entries we haven't got a DumpableObject for */
                              10722         [ +  + ]:          43130 :             if (dobj)
                              10723                 :                :             {
                              10724                 :                :                 /* Cope with sub-object initprivs */
                              10725         [ +  + ]:          30919 :                 if (objsubid != 0)
                              10726                 :                :                 {
                              10727         [ +  - ]:           3684 :                     if (dobj->objType == DO_TABLE)
                              10728                 :                :                     {
                              10729                 :                :                         /* For a column initprivs, set the table's ACL flags */
                              10730                 :           3684 :                         dobj->components |= DUMP_COMPONENT_ACL;
                              10731                 :           3684 :                         ((TableInfo *) dobj)->hascolumnACLs = true;
                              10732                 :                :                     }
                              10733                 :                :                     else
 1370 tgl@sss.pgh.pa.us       10734                 :UBC           0 :                         pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10735                 :                :                                        classoid, objoid, objsubid);
 1370 tgl@sss.pgh.pa.us       10736                 :CBC        3863 :                     continue;
                              10737                 :                :                 }
                              10738                 :                : 
                              10739                 :                :                 /*
                              10740                 :                :                  * We ignore any pg_init_privs.initprivs entry for the public
                              10741                 :                :                  * schema, as explained in getNamespaces().
                              10742                 :                :                  */
                              10743         [ +  + ]:          27235 :                 if (dobj->objType == DO_NAMESPACE &&
                              10744         [ +  + ]:            362 :                     strcmp(dobj->name, "public") == 0)
                              10745                 :            179 :                     continue;
                              10746                 :                : 
                              10747                 :                :                 /* Else it had better be of a type we think has ACLs */
                              10748         [ +  + ]:          27056 :                 if (dobj->objType == DO_NAMESPACE ||
                              10749         [ +  + ]:          26873 :                     dobj->objType == DO_TYPE ||
                              10750         [ +  + ]:          26849 :                     dobj->objType == DO_FUNC ||
                              10751         [ +  + ]:          26751 :                     dobj->objType == DO_AGG ||
                              10752         [ -  + ]:          26727 :                     dobj->objType == DO_TABLE ||
 1370 tgl@sss.pgh.pa.us       10753         [ #  # ]:UBC           0 :                     dobj->objType == DO_PROCLANG ||
                              10754         [ #  # ]:              0 :                     dobj->objType == DO_FDW ||
                              10755         [ #  # ]:              0 :                     dobj->objType == DO_FOREIGN_SERVER)
 1370 tgl@sss.pgh.pa.us       10756                 :CBC       27056 :                 {
                              10757                 :          27056 :                     DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
                              10758                 :                : 
                              10759                 :          27056 :                     daobj->dacl.privtype = privtype;
                              10760                 :          27056 :                     daobj->dacl.initprivs = pstrdup(initprivs);
                              10761                 :                :                 }
                              10762                 :                :                 else
 1370 tgl@sss.pgh.pa.us       10763                 :UBC           0 :                     pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10764                 :                :                                    classoid, objoid, objsubid);
                              10765                 :                :             }
                              10766                 :                :         }
 1370 tgl@sss.pgh.pa.us       10767                 :CBC         183 :         PQclear(res);
                              10768                 :                :     }
                              10769                 :                : 
                              10770                 :            183 :     destroyPQExpBuffer(query);
                              10771                 :            183 : }
                              10772                 :                : 
                              10773                 :                : /*
                              10774                 :                :  * dumpCommentExtended --
                              10775                 :                :  *
                              10776                 :                :  * This routine is used to dump any comments associated with the
                              10777                 :                :  * object handed to this routine. The routine takes the object type
                              10778                 :                :  * and object name (ready to print, except for schema decoration), plus
                              10779                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              10780                 :                :  * plus catalog ID and subid which are the lookup key for pg_description,
                              10781                 :                :  * plus the dump ID for the object (for setting a dependency).
                              10782                 :                :  * If a matching pg_description entry is found, it is dumped.
                              10783                 :                :  *
                              10784                 :                :  * Note: in some cases, such as comments for triggers and rules, the "type"
                              10785                 :                :  * string really looks like, e.g., "TRIGGER name ON".  This is a bit of a hack
                              10786                 :                :  * but it doesn't seem worth complicating the API for all callers to make
                              10787                 :                :  * it cleaner.
                              10788                 :                :  *
                              10789                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              10790                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              10791                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              10792                 :                :  * ordering of the comment in the dump file, because this routine is called
                              10793                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              10794                 :                :  * calling ArchiveEntry() for the specified object.
                              10795                 :                :  */
                              10796                 :                : static void
 1531 noah@leadboat.com       10797                 :           6666 : dumpCommentExtended(Archive *fout, const char *type,
                              10798                 :                :                     const char *name, const char *namespace,
                              10799                 :                :                     const char *owner, CatalogId catalogId,
                              10800                 :                :                     int subid, DumpId dumpId,
                              10801                 :                :                     const char *initdb_comment)
                              10802                 :                : {
 3524 tgl@sss.pgh.pa.us       10803                 :           6666 :     DumpOptions *dopt = fout->dopt;
                              10804                 :                :     CommentItem *comments;
                              10805                 :                :     int         ncomments;
                              10806                 :                : 
                              10807                 :                :     /* do nothing, if --no-comments is supplied */
 2781                         10808         [ -  + ]:           6666 :     if (dopt->no_comments)
 2781 tgl@sss.pgh.pa.us       10809                 :UBC           0 :         return;
                              10810                 :                : 
                              10811                 :                :     /* Comments are schema not data ... except LO comments are data */
 2749 tgl@sss.pgh.pa.us       10812         [ +  + ]:CBC        6666 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              10813                 :                :     {
  285 nathan@postgresql.or    10814         [ -  + ]:           6611 :         if (!dopt->dumpSchema)
 5679 tgl@sss.pgh.pa.us       10815                 :UBC           0 :             return;
                              10816                 :                :     }
                              10817                 :                :     else
                              10818                 :                :     {
                              10819                 :                :         /* We do dump LO comments in binary-upgrade mode */
  285 nathan@postgresql.or    10820   [ +  +  -  + ]:CBC          55 :         if (!dopt->dumpData && !dopt->binary_upgrade)
 5679 tgl@sss.pgh.pa.us       10821                 :UBC           0 :             return;
                              10822                 :                :     }
                              10823                 :                : 
                              10824                 :                :     /* Search for comments associated with catalogId, using table */
 1346 tgl@sss.pgh.pa.us       10825                 :CBC        6666 :     ncomments = findComments(catalogId.tableoid, catalogId.oid,
                              10826                 :                :                              &comments);
                              10827                 :                : 
                              10828                 :                :     /* Is there one matching the subid? */
 7840                         10829         [ +  + ]:           6666 :     while (ncomments > 0)
                              10830                 :                :     {
                              10831         [ +  - ]:           6619 :         if (comments->objsubid == subid)
                              10832                 :           6619 :             break;
 7840 tgl@sss.pgh.pa.us       10833                 :UBC           0 :         comments++;
                              10834                 :              0 :         ncomments--;
                              10835                 :                :     }
                              10836                 :                : 
 1531 noah@leadboat.com       10837         [ +  + ]:CBC        6666 :     if (initdb_comment != NULL)
                              10838                 :                :     {
                              10839                 :                :         static CommentItem empty_comment = {.descr = ""};
                              10840                 :                : 
                              10841                 :                :         /*
                              10842                 :                :          * initdb creates this object with a comment.  Skip dumping the
                              10843                 :                :          * initdb-provided comment, which would complicate matters for
                              10844                 :                :          * non-superuser use of pg_dump.  When the DBA has removed initdb's
                              10845                 :                :          * comment, replicate that.
                              10846                 :                :          */
                              10847         [ +  + ]:            116 :         if (ncomments == 0)
                              10848                 :                :         {
                              10849                 :              4 :             comments = &empty_comment;
                              10850                 :              4 :             ncomments = 1;
                              10851                 :                :         }
                              10852         [ +  - ]:            112 :         else if (strcmp(comments->descr, initdb_comment) == 0)
                              10853                 :            112 :             ncomments = 0;
                              10854                 :                :     }
                              10855                 :                : 
                              10856                 :                :     /* If a comment exists, build COMMENT ON statement */
 7840 tgl@sss.pgh.pa.us       10857         [ +  + ]:           6666 :     if (ncomments > 0)
                              10858                 :                :     {
                              10859                 :           6511 :         PQExpBuffer query = createPQExpBuffer();
 2749                         10860                 :           6511 :         PQExpBuffer tag = createPQExpBuffer();
                              10861                 :                : 
                              10862                 :           6511 :         appendPQExpBuffer(query, "COMMENT ON %s ", type);
                              10863   [ +  +  +  - ]:           6511 :         if (namespace && *namespace)
                              10864                 :           6326 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
                              10865                 :           6511 :         appendPQExpBuffer(query, "%s IS ", name);
 7041                         10866                 :           6511 :         appendStringLiteralAH(query, comments->descr, fout);
 4310 heikki.linnakangas@i    10867                 :           6511 :         appendPQExpBufferStr(query, ";\n");
                              10868                 :                : 
 2749 tgl@sss.pgh.pa.us       10869                 :           6511 :         appendPQExpBuffer(tag, "%s %s", type, name);
                              10870                 :                : 
                              10871                 :                :         /*
                              10872                 :                :          * We mark comments as SECTION_NONE because they really belong in the
                              10873                 :                :          * same section as their parent, whether that is pre-data or
                              10874                 :                :          * post-data.
                              10875                 :                :          */
 7945                         10876                 :           6511 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    10877                 :           6511 :                      ARCHIVE_OPTS(.tag = tag->data,
                              10878                 :                :                                   .namespace = namespace,
                              10879                 :                :                                   .owner = owner,
                              10880                 :                :                                   .description = "COMMENT",
                              10881                 :                :                                   .section = SECTION_NONE,
                              10882                 :                :                                   .createStmt = query->data,
                              10883                 :                :                                   .deps = &dumpId,
                              10884                 :                :                                   .nDeps = 1));
                              10885                 :                : 
 7840 tgl@sss.pgh.pa.us       10886                 :           6511 :         destroyPQExpBuffer(query);
 2749                         10887                 :           6511 :         destroyPQExpBuffer(tag);
                              10888                 :                :     }
                              10889                 :                : }
                              10890                 :                : 
                              10891                 :                : /*
                              10892                 :                :  * dumpComment --
                              10893                 :                :  *
                              10894                 :                :  * Typical simplification of the above function.
                              10895                 :                :  */
                              10896                 :                : static inline void
 1531 noah@leadboat.com       10897                 :           6511 : dumpComment(Archive *fout, const char *type,
                              10898                 :                :             const char *name, const char *namespace,
                              10899                 :                :             const char *owner, CatalogId catalogId,
                              10900                 :                :             int subid, DumpId dumpId)
                              10901                 :                : {
                              10902                 :           6511 :     dumpCommentExtended(fout, type, name, namespace, owner,
                              10903                 :                :                         catalogId, subid, dumpId, NULL);
                              10904                 :           6511 : }
                              10905                 :                : 
                              10906                 :                : /*
                              10907                 :                :  * appendNamedArgument --
                              10908                 :                :  *
                              10909                 :                :  * Convenience routine for constructing parameters of the form:
                              10910                 :                :  * 'paraname', 'value'::type
                              10911                 :                :  */
                              10912                 :                : static void
  198 jdavis@postgresql.or    10913                 :           5700 : appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
                              10914                 :                :                     const char *argtype, const char *argval)
                              10915                 :                : {
  192 tgl@sss.pgh.pa.us       10916                 :           5700 :     appendPQExpBufferStr(out, ",\n\t");
                              10917                 :                : 
  198 jdavis@postgresql.or    10918                 :           5700 :     appendStringLiteralAH(out, argname, fout);
                              10919                 :           5700 :     appendPQExpBufferStr(out, ", ");
                              10920                 :                : 
                              10921                 :           5700 :     appendStringLiteralAH(out, argval, fout);
                              10922                 :           5700 :     appendPQExpBuffer(out, "::%s", argtype);
                              10923                 :           5700 : }
                              10924                 :                : 
                              10925                 :                : /*
                              10926                 :                :  * fetchAttributeStats --
                              10927                 :                :  *
                              10928                 :                :  * Fetch next batch of attribute statistics for dumpRelationStats_dumper().
                              10929                 :                :  */
                              10930                 :                : static PGresult *
  155 nathan@postgresql.or    10931                 :           1198 : fetchAttributeStats(Archive *fout)
                              10932                 :                : {
                              10933                 :           1198 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                              10934                 :           1198 :     PQExpBuffer nspnames = createPQExpBuffer();
                              10935                 :           1198 :     PQExpBuffer relnames = createPQExpBuffer();
                              10936                 :           1198 :     int         count = 0;
                              10937                 :           1198 :     PGresult   *res = NULL;
                              10938                 :                :     static TocEntry *te;
                              10939                 :                :     static bool restarted;
                              10940                 :           1198 :     int         max_rels = MAX_ATTR_STATS_RELS;
                              10941                 :                : 
                              10942                 :                :     /*
                              10943                 :                :      * Our query for retrieving statistics for multiple relations uses WITH
                              10944                 :                :      * ORDINALITY and multi-argument UNNEST(), both of which were introduced
                              10945                 :                :      * in v9.4.  For older versions, we resort to gathering statistics for a
                              10946                 :                :      * single relation at a time.
                              10947                 :                :      */
                              10948         [ -  + ]:           1198 :     if (fout->remoteVersion < 90400)
  155 nathan@postgresql.or    10949                 :UBC           0 :         max_rels = 1;
                              10950                 :                : 
                              10951                 :                :     /* If we're just starting, set our TOC pointer. */
  155 nathan@postgresql.or    10952         [ +  + ]:CBC        1198 :     if (!te)
                              10953                 :             60 :         te = AH->toc->next;
                              10954                 :                : 
                              10955                 :                :     /*
                              10956                 :                :      * We can't easily avoid a second TOC scan for the tar format because it
                              10957                 :                :      * writes restore.sql separately, which means we must execute the queries
                              10958                 :                :      * twice.  This feels risky, but there is no known reason it should
                              10959                 :                :      * generate different output than the first pass.  Even if it does, the
                              10960                 :                :      * worst-case scenario is that restore.sql might have different statistics
                              10961                 :                :      * data than the archive.
                              10962                 :                :      */
                              10963   [ +  +  +  +  :           1198 :     if (!restarted && te == AH->toc && AH->format == archTar)
                                              +  + ]
                              10964                 :                :     {
                              10965                 :              1 :         te = AH->toc->next;
                              10966                 :              1 :         restarted = true;
                              10967                 :                :     }
                              10968                 :                : 
  109                         10969                 :           1198 :     appendPQExpBufferChar(nspnames, '{');
                              10970                 :           1198 :     appendPQExpBufferChar(relnames, '{');
                              10971                 :                : 
                              10972                 :                :     /*
                              10973                 :                :      * Scan the TOC for the next set of relevant stats entries.  We assume
                              10974                 :                :      * that statistics are dumped in the order they are listed in the TOC.
                              10975                 :                :      * This is perhaps not the sturdiest assumption, so we verify it matches
                              10976                 :                :      * reality in dumpRelationStats_dumper().
                              10977                 :                :      */
  155                         10978   [ +  +  +  + ]:          18109 :     for (; te != AH->toc && count < max_rels; te = te->next)
                              10979                 :                :     {
                              10980         [ +  + ]:          16911 :         if ((te->reqs & REQ_STATS) != 0 &&
                              10981         [ +  - ]:           3720 :             strcmp(te->desc, "STATISTICS DATA") == 0)
                              10982                 :                :         {
  109                         10983                 :           3720 :             appendPGArray(nspnames, te->namespace);
                              10984                 :           3720 :             appendPGArray(relnames, te->tag);
  155                         10985                 :           3720 :             count++;
                              10986                 :                :         }
                              10987                 :                :     }
                              10988                 :                : 
  109                         10989                 :           1198 :     appendPQExpBufferChar(nspnames, '}');
                              10990                 :           1198 :     appendPQExpBufferChar(relnames, '}');
                              10991                 :                : 
                              10992                 :                :     /* Execute the query for the next batch of relations. */
  155                         10993         [ +  + ]:           1198 :     if (count > 0)
                              10994                 :                :     {
                              10995                 :            109 :         PQExpBuffer query = createPQExpBuffer();
                              10996                 :                : 
  109                         10997                 :            109 :         appendPQExpBufferStr(query, "EXECUTE getAttributeStats(");
                              10998                 :            109 :         appendStringLiteralAH(query, nspnames->data, fout);
                              10999                 :            109 :         appendPQExpBufferStr(query, "::pg_catalog.name[],");
                              11000                 :            109 :         appendStringLiteralAH(query, relnames->data, fout);
                              11001                 :            109 :         appendPQExpBufferStr(query, "::pg_catalog.name[])");
  155                         11002                 :            109 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11003                 :            109 :         destroyPQExpBuffer(query);
                              11004                 :                :     }
                              11005                 :                : 
                              11006                 :           1198 :     destroyPQExpBuffer(nspnames);
                              11007                 :           1198 :     destroyPQExpBuffer(relnames);
                              11008                 :           1198 :     return res;
                              11009                 :                : }
                              11010                 :                : 
                              11011                 :                : /*
                              11012                 :                :  * dumpRelationStats_dumper --
                              11013                 :                :  *
                              11014                 :                :  * Generate command to import stats into the relation on the new database.
                              11015                 :                :  * This routine is called by the Archiver when it wants the statistics to be
                              11016                 :                :  * dumped.
                              11017                 :                :  */
                              11018                 :                : static char *
                              11019                 :           3720 : dumpRelationStats_dumper(Archive *fout, const void *userArg, const TocEntry *te)
                              11020                 :                : {
                              11021                 :           3720 :     const RelStatsInfo *rsinfo = (RelStatsInfo *) userArg;
                              11022                 :                :     static PGresult *res;
                              11023                 :                :     static int  rownum;
                              11024                 :                :     PQExpBuffer query;
                              11025                 :                :     PQExpBufferData out_data;
                              11026                 :           3720 :     PQExpBuffer out = &out_data;
                              11027                 :                :     int         i_schemaname;
                              11028                 :                :     int         i_tablename;
                              11029                 :                :     int         i_attname;
                              11030                 :                :     int         i_inherited;
                              11031                 :                :     int         i_null_frac;
                              11032                 :                :     int         i_avg_width;
                              11033                 :                :     int         i_n_distinct;
                              11034                 :                :     int         i_most_common_vals;
                              11035                 :                :     int         i_most_common_freqs;
                              11036                 :                :     int         i_histogram_bounds;
                              11037                 :                :     int         i_correlation;
                              11038                 :                :     int         i_most_common_elems;
                              11039                 :                :     int         i_most_common_elem_freqs;
                              11040                 :                :     int         i_elem_count_histogram;
                              11041                 :                :     int         i_range_length_histogram;
                              11042                 :                :     int         i_range_empty_frac;
                              11043                 :                :     int         i_range_bounds_histogram;
                              11044                 :                :     static TocEntry *expected_te;
                              11045                 :                : 
                              11046                 :                :     /*
                              11047                 :                :      * fetchAttributeStats() assumes that the statistics are dumped in the
                              11048                 :                :      * order they are listed in the TOC.  We verify that here for safety.
                              11049                 :                :      */
                              11050         [ +  + ]:           3720 :     if (!expected_te)
                              11051                 :             60 :         expected_te = ((ArchiveHandle *) fout)->toc;
                              11052                 :                : 
                              11053                 :           3720 :     expected_te = expected_te->next;
                              11054         [ +  + ]:          14912 :     while ((expected_te->reqs & REQ_STATS) == 0 ||
                              11055         [ -  + ]:           3720 :            strcmp(expected_te->desc, "STATISTICS DATA") != 0)
                              11056                 :          11192 :         expected_te = expected_te->next;
                              11057                 :                : 
                              11058         [ -  + ]:           3720 :     if (te != expected_te)
   82 peter@eisentraut.org    11059                 :UBC           0 :         pg_fatal("statistics dumped out of order (current: %d %s %s, expected: %d %s %s)",
                              11060                 :                :                  te->dumpId, te->desc, te->tag,
                              11061                 :                :                  expected_te->dumpId, expected_te->desc, expected_te->tag);
                              11062                 :                : 
  193 jdavis@postgresql.or    11063                 :CBC        3720 :     query = createPQExpBuffer();
                              11064         [ +  + ]:           3720 :     if (!fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS])
                              11065                 :                :     {
                              11066                 :             60 :         appendPQExpBufferStr(query,
                              11067                 :                :                              "PREPARE getAttributeStats(pg_catalog.name[], pg_catalog.name[]) AS\n"
                              11068                 :                :                              "SELECT s.schemaname, s.tablename, s.attname, s.inherited, "
                              11069                 :                :                              "s.null_frac, s.avg_width, s.n_distinct, "
                              11070                 :                :                              "s.most_common_vals, s.most_common_freqs, "
                              11071                 :                :                              "s.histogram_bounds, s.correlation, "
                              11072                 :                :                              "s.most_common_elems, s.most_common_elem_freqs, "
                              11073                 :                :                              "s.elem_count_histogram, ");
                              11074                 :                : 
                              11075         [ +  - ]:             60 :         if (fout->remoteVersion >= 170000)
                              11076                 :             60 :             appendPQExpBufferStr(query,
                              11077                 :                :                                  "s.range_length_histogram, "
                              11078                 :                :                                  "s.range_empty_frac, "
                              11079                 :                :                                  "s.range_bounds_histogram ");
                              11080                 :                :         else
  193 jdavis@postgresql.or    11081                 :UBC           0 :             appendPQExpBufferStr(query,
                              11082                 :                :                                  "NULL AS range_length_histogram,"
                              11083                 :                :                                  "NULL AS range_empty_frac,"
                              11084                 :                :                                  "NULL AS range_bounds_histogram ");
                              11085                 :                : 
                              11086                 :                :         /*
                              11087                 :                :          * The results must be in the order of the relations supplied in the
                              11088                 :                :          * parameters to ensure we remain in sync as we walk through the TOC.
                              11089                 :                :          * The redundant filter clause on s.tablename = ANY(...) seems
                              11090                 :                :          * sufficient to convince the planner to use
                              11091                 :                :          * pg_class_relname_nsp_index, which avoids a full scan of pg_stats.
                              11092                 :                :          * This may not work for all versions.
                              11093                 :                :          *
                              11094                 :                :          * Our query for retrieving statistics for multiple relations uses
                              11095                 :                :          * WITH ORDINALITY and multi-argument UNNEST(), both of which were
                              11096                 :                :          * introduced in v9.4.  For older versions, we resort to gathering
                              11097                 :                :          * statistics for a single relation at a time.
                              11098                 :                :          */
  155 nathan@postgresql.or    11099         [ +  - ]:CBC          60 :         if (fout->remoteVersion >= 90400)
                              11100                 :             60 :             appendPQExpBufferStr(query,
                              11101                 :                :                                  "FROM pg_catalog.pg_stats s "
                              11102                 :                :                                  "JOIN unnest($1, $2) WITH ORDINALITY AS u (schemaname, tablename, ord) "
                              11103                 :                :                                  "ON s.schemaname = u.schemaname "
                              11104                 :                :                                  "AND s.tablename = u.tablename "
                              11105                 :                :                                  "WHERE s.tablename = ANY($2) "
                              11106                 :                :                                  "ORDER BY u.ord, s.attname, s.inherited");
                              11107                 :                :         else
  155 nathan@postgresql.or    11108                 :UBC           0 :             appendPQExpBufferStr(query,
                              11109                 :                :                                  "FROM pg_catalog.pg_stats s "
                              11110                 :                :                                  "WHERE s.schemaname = $1[1] "
                              11111                 :                :                                  "AND s.tablename = $2[1] "
                              11112                 :                :                                  "ORDER BY s.attname, s.inherited");
                              11113                 :                : 
  193 jdavis@postgresql.or    11114                 :CBC          60 :         ExecuteSqlStatement(fout, query->data);
                              11115                 :                : 
                              11116                 :             60 :         fout->is_prepared[PREPQUERY_GETATTRIBUTESTATS] = true;
                              11117                 :             60 :         resetPQExpBuffer(query);
                              11118                 :                :     }
                              11119                 :                : 
  155 nathan@postgresql.or    11120                 :           3720 :     initPQExpBuffer(out);
                              11121                 :                : 
                              11122                 :                :     /* restore relation stats */
  192 tgl@sss.pgh.pa.us       11123                 :           3720 :     appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
  149 peter@eisentraut.org    11124                 :           3720 :     appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
                              11125                 :                :                       fout->remoteVersion);
  165 jdavis@postgresql.or    11126                 :           3720 :     appendPQExpBufferStr(out, "\t'schemaname', ");
                              11127                 :           3720 :     appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
                              11128                 :           3720 :     appendPQExpBufferStr(out, ",\n");
                              11129                 :           3720 :     appendPQExpBufferStr(out, "\t'relname', ");
                              11130                 :           3720 :     appendStringLiteralAH(out, rsinfo->dobj.name, fout);
                              11131                 :           3720 :     appendPQExpBufferStr(out, ",\n");
  192 tgl@sss.pgh.pa.us       11132                 :           3720 :     appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
                              11133                 :                : 
                              11134                 :                :     /*
                              11135                 :                :      * Before v14, a reltuples value of 0 was ambiguous: it could either mean
                              11136                 :                :      * the relation is empty, or it could mean that it hadn't yet been
                              11137                 :                :      * vacuumed or analyzed.  (Newer versions use -1 for the latter case.)
                              11138                 :                :      * This ambiguity allegedly can cause the planner to choose inefficient
                              11139                 :                :      * plans after restoring to v18 or newer.  To deal with this, let's just
                              11140                 :                :      * set reltuples to -1 in that case.
                              11141                 :                :      */
  107 nathan@postgresql.or    11142   [ -  +  -  - ]:           3720 :     if (fout->remoteVersion < 140000 && strcmp("0", rsinfo->reltuples) == 0)
  107 nathan@postgresql.or    11143                 :UBC           0 :         appendPQExpBufferStr(out, "\t'reltuples', '-1'::real,\n");
                              11144                 :                :     else
  107 nathan@postgresql.or    11145                 :CBC        3720 :         appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", rsinfo->reltuples);
                              11146                 :                : 
  160 jdavis@postgresql.or    11147                 :           3720 :     appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer",
  192 tgl@sss.pgh.pa.us       11148                 :           3720 :                       rsinfo->relallvisible);
                              11149                 :                : 
  160 jdavis@postgresql.or    11150         [ +  - ]:           3720 :     if (fout->remoteVersion >= 180000)
                              11151                 :           3720 :         appendPQExpBuffer(out, ",\n\t'relallfrozen', '%d'::integer", rsinfo->relallfrozen);
                              11152                 :                : 
                              11153                 :           3720 :     appendPQExpBufferStr(out, "\n);\n");
                              11154                 :                : 
                              11155                 :                :     /* Fetch the next batch of attribute statistics if needed. */
  155 nathan@postgresql.or    11156         [ +  + ]:           3720 :     if (rownum >= PQntuples(res))
                              11157                 :                :     {
                              11158                 :           1198 :         PQclear(res);
                              11159                 :           1198 :         res = fetchAttributeStats(fout);
                              11160                 :           1198 :         rownum = 0;
                              11161                 :                :     }
                              11162                 :                : 
                              11163                 :           3720 :     i_schemaname = PQfnumber(res, "schemaname");
                              11164                 :           3720 :     i_tablename = PQfnumber(res, "tablename");
  192 tgl@sss.pgh.pa.us       11165                 :           3720 :     i_attname = PQfnumber(res, "attname");
                              11166                 :           3720 :     i_inherited = PQfnumber(res, "inherited");
                              11167                 :           3720 :     i_null_frac = PQfnumber(res, "null_frac");
                              11168                 :           3720 :     i_avg_width = PQfnumber(res, "avg_width");
                              11169                 :           3720 :     i_n_distinct = PQfnumber(res, "n_distinct");
                              11170                 :           3720 :     i_most_common_vals = PQfnumber(res, "most_common_vals");
                              11171                 :           3720 :     i_most_common_freqs = PQfnumber(res, "most_common_freqs");
                              11172                 :           3720 :     i_histogram_bounds = PQfnumber(res, "histogram_bounds");
                              11173                 :           3720 :     i_correlation = PQfnumber(res, "correlation");
                              11174                 :           3720 :     i_most_common_elems = PQfnumber(res, "most_common_elems");
                              11175                 :           3720 :     i_most_common_elem_freqs = PQfnumber(res, "most_common_elem_freqs");
                              11176                 :           3720 :     i_elem_count_histogram = PQfnumber(res, "elem_count_histogram");
                              11177                 :           3720 :     i_range_length_histogram = PQfnumber(res, "range_length_histogram");
                              11178                 :           3720 :     i_range_empty_frac = PQfnumber(res, "range_empty_frac");
                              11179                 :           3720 :     i_range_bounds_histogram = PQfnumber(res, "range_bounds_histogram");
                              11180                 :                : 
                              11181                 :                :     /* restore attribute stats */
  155 nathan@postgresql.or    11182         [ +  + ]:           4577 :     for (; rownum < PQntuples(res); rownum++)
                              11183                 :                :     {
                              11184                 :                :         const char *attname;
                              11185                 :                : 
                              11186                 :                :         /* Stop if the next stat row in our cache isn't for this relation. */
                              11187         [ +  + ]:           3379 :         if (strcmp(te->tag, PQgetvalue(res, rownum, i_tablename)) != 0 ||
                              11188         [ +  - ]:            857 :             strcmp(te->namespace, PQgetvalue(res, rownum, i_schemaname)) != 0)
                              11189                 :                :             break;
                              11190                 :                : 
  192 tgl@sss.pgh.pa.us       11191                 :            857 :         appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_attribute_stats(\n");
  149 peter@eisentraut.org    11192                 :            857 :         appendPQExpBuffer(out, "\t'version', '%d'::integer,\n",
                              11193                 :                :                           fout->remoteVersion);
  165 jdavis@postgresql.or    11194                 :            857 :         appendPQExpBufferStr(out, "\t'schemaname', ");
                              11195                 :            857 :         appendStringLiteralAH(out, rsinfo->dobj.namespace->dobj.name, fout);
                              11196                 :            857 :         appendPQExpBufferStr(out, ",\n\t'relname', ");
                              11197                 :            857 :         appendStringLiteralAH(out, rsinfo->dobj.name, fout);
                              11198                 :                : 
  192 tgl@sss.pgh.pa.us       11199         [ -  + ]:            857 :         if (PQgetisnull(res, rownum, i_attname))
   82 peter@eisentraut.org    11200                 :UBC           0 :             pg_fatal("unexpected null attname");
  192 tgl@sss.pgh.pa.us       11201                 :CBC         857 :         attname = PQgetvalue(res, rownum, i_attname);
                              11202                 :                : 
                              11203                 :                :         /*
                              11204                 :                :          * Indexes look up attname in indAttNames to derive attnum, all others
                              11205                 :                :          * use attname directly.  We must specify attnum for indexes, since
                              11206                 :                :          * their attnames are not necessarily stable across dump/reload.
                              11207                 :                :          */
                              11208         [ +  + ]:            857 :         if (rsinfo->nindAttNames == 0)
                              11209                 :                :         {
  142 drowley@postgresql.o    11210                 :            816 :             appendPQExpBufferStr(out, ",\n\t'attname', ");
  165 jdavis@postgresql.or    11211                 :            816 :             appendStringLiteralAH(out, attname, fout);
                              11212                 :                :         }
                              11213                 :                :         else
                              11214                 :                :         {
  192 tgl@sss.pgh.pa.us       11215                 :             41 :             bool        found = false;
                              11216                 :                : 
                              11217         [ +  - ]:             78 :             for (int i = 0; i < rsinfo->nindAttNames; i++)
                              11218                 :                :             {
                              11219         [ +  + ]:             78 :                 if (strcmp(attname, rsinfo->indAttNames[i]) == 0)
                              11220                 :                :                 {
                              11221                 :             41 :                     appendPQExpBuffer(out, ",\n\t'attnum', '%d'::smallint",
                              11222                 :                :                                       i + 1);
                              11223                 :             41 :                     found = true;
                              11224                 :             41 :                     break;
                              11225                 :                :                 }
                              11226                 :                :             }
                              11227                 :                : 
                              11228         [ -  + ]:             41 :             if (!found)
  192 tgl@sss.pgh.pa.us       11229                 :UBC           0 :                 pg_fatal("could not find index attname \"%s\"", attname);
                              11230                 :                :         }
                              11231                 :                : 
  192 tgl@sss.pgh.pa.us       11232         [ +  - ]:CBC         857 :         if (!PQgetisnull(res, rownum, i_inherited))
                              11233                 :            857 :             appendNamedArgument(out, fout, "inherited", "boolean",
                              11234                 :            857 :                                 PQgetvalue(res, rownum, i_inherited));
                              11235         [ +  - ]:            857 :         if (!PQgetisnull(res, rownum, i_null_frac))
                              11236                 :            857 :             appendNamedArgument(out, fout, "null_frac", "real",
                              11237                 :            857 :                                 PQgetvalue(res, rownum, i_null_frac));
                              11238         [ +  - ]:            857 :         if (!PQgetisnull(res, rownum, i_avg_width))
                              11239                 :            857 :             appendNamedArgument(out, fout, "avg_width", "integer",
                              11240                 :            857 :                                 PQgetvalue(res, rownum, i_avg_width));
                              11241         [ +  - ]:            857 :         if (!PQgetisnull(res, rownum, i_n_distinct))
                              11242                 :            857 :             appendNamedArgument(out, fout, "n_distinct", "real",
                              11243                 :            857 :                                 PQgetvalue(res, rownum, i_n_distinct));
                              11244         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_most_common_vals))
                              11245                 :            441 :             appendNamedArgument(out, fout, "most_common_vals", "text",
                              11246                 :            441 :                                 PQgetvalue(res, rownum, i_most_common_vals));
                              11247         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_most_common_freqs))
                              11248                 :            441 :             appendNamedArgument(out, fout, "most_common_freqs", "real[]",
                              11249                 :            441 :                                 PQgetvalue(res, rownum, i_most_common_freqs));
                              11250         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_histogram_bounds))
                              11251                 :            538 :             appendNamedArgument(out, fout, "histogram_bounds", "text",
                              11252                 :            538 :                                 PQgetvalue(res, rownum, i_histogram_bounds));
                              11253         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_correlation))
                              11254                 :            817 :             appendNamedArgument(out, fout, "correlation", "real",
                              11255                 :            817 :                                 PQgetvalue(res, rownum, i_correlation));
                              11256         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_most_common_elems))
                              11257                 :              8 :             appendNamedArgument(out, fout, "most_common_elems", "text",
                              11258                 :              8 :                                 PQgetvalue(res, rownum, i_most_common_elems));
                              11259         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_most_common_elem_freqs))
                              11260                 :              8 :             appendNamedArgument(out, fout, "most_common_elem_freqs", "real[]",
                              11261                 :              8 :                                 PQgetvalue(res, rownum, i_most_common_elem_freqs));
                              11262         [ +  + ]:            857 :         if (!PQgetisnull(res, rownum, i_elem_count_histogram))
                              11263                 :              7 :             appendNamedArgument(out, fout, "elem_count_histogram", "real[]",
                              11264                 :              7 :                                 PQgetvalue(res, rownum, i_elem_count_histogram));
                              11265         [ +  - ]:            857 :         if (fout->remoteVersion >= 170000)
                              11266                 :                :         {
                              11267         [ +  + ]:            857 :             if (!PQgetisnull(res, rownum, i_range_length_histogram))
                              11268                 :              4 :                 appendNamedArgument(out, fout, "range_length_histogram", "text",
                              11269                 :              4 :                                     PQgetvalue(res, rownum, i_range_length_histogram));
                              11270         [ +  + ]:            857 :             if (!PQgetisnull(res, rownum, i_range_empty_frac))
                              11271                 :              4 :                 appendNamedArgument(out, fout, "range_empty_frac", "real",
                              11272                 :              4 :                                     PQgetvalue(res, rownum, i_range_empty_frac));
                              11273         [ +  + ]:            857 :             if (!PQgetisnull(res, rownum, i_range_bounds_histogram))
                              11274                 :              4 :                 appendNamedArgument(out, fout, "range_bounds_histogram", "text",
                              11275                 :              4 :                                     PQgetvalue(res, rownum, i_range_bounds_histogram));
                              11276                 :                :         }
                              11277                 :            857 :         appendPQExpBufferStr(out, "\n);\n");
                              11278                 :                :     }
                              11279                 :                : 
  155 nathan@postgresql.or    11280                 :           3720 :     destroyPQExpBuffer(query);
                              11281                 :           3720 :     return out->data;
                              11282                 :                : }
                              11283                 :                : 
                              11284                 :                : /*
                              11285                 :                :  * dumpRelationStats --
                              11286                 :                :  *
                              11287                 :                :  * Make an ArchiveEntry for the relation statistics.  The Archiver will take
                              11288                 :                :  * care of gathering the statistics and generating the restore commands when
                              11289                 :                :  * they are needed.
                              11290                 :                :  */
                              11291                 :                : static void
                              11292                 :           3792 : dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
                              11293                 :                : {
                              11294                 :           3792 :     const DumpableObject *dobj = &rsinfo->dobj;
                              11295                 :                : 
                              11296                 :                :     /* nothing to do if we are not dumping statistics */
                              11297         [ -  + ]:           3792 :     if (!fout->dopt->dumpStatistics)
  155 nathan@postgresql.or    11298                 :UBC           0 :         return;
                              11299                 :                : 
  198 jdavis@postgresql.or    11300                 :CBC        3792 :     ArchiveEntry(fout, nilCatalogId, createDumpId(),
  191                         11301                 :           3792 :                  ARCHIVE_OPTS(.tag = dobj->name,
                              11302                 :                :                               .namespace = dobj->namespace->dobj.name,
                              11303                 :                :                               .description = "STATISTICS DATA",
                              11304                 :                :                               .section = rsinfo->section,
                              11305                 :                :                               .defnFn = dumpRelationStats_dumper,
                              11306                 :                :                               .defnArg = rsinfo,
                              11307                 :                :                               .deps = dobj->dependencies,
                              11308                 :                :                               .nDeps = dobj->nDeps));
                              11309                 :                : }
                              11310                 :                : 
                              11311                 :                : /*
                              11312                 :                :  * dumpTableComment --
                              11313                 :                :  *
                              11314                 :                :  * As above, but dump comments for both the specified table (or view)
                              11315                 :                :  * and its columns.
                              11316                 :                :  */
                              11317                 :                : static void
 1669 peter@eisentraut.org    11318                 :             86 : dumpTableComment(Archive *fout, const TableInfo *tbinfo,
                              11319                 :                :                  const char *reltypename)
                              11320                 :                : {
 3524 tgl@sss.pgh.pa.us       11321                 :             86 :     DumpOptions *dopt = fout->dopt;
                              11322                 :                :     CommentItem *comments;
                              11323                 :                :     int         ncomments;
                              11324                 :                :     PQExpBuffer query;
                              11325                 :                :     PQExpBuffer tag;
                              11326                 :                : 
                              11327                 :                :     /* do nothing, if --no-comments is supplied */
 2781                         11328         [ -  + ]:             86 :     if (dopt->no_comments)
 2781 tgl@sss.pgh.pa.us       11329                 :UBC           0 :         return;
                              11330                 :                : 
                              11331                 :                :     /* Comments are SCHEMA not data */
  285 nathan@postgresql.or    11332         [ -  + ]:CBC          86 :     if (!dopt->dumpSchema)
 8520 tgl@sss.pgh.pa.us       11333                 :UBC           0 :         return;
                              11334                 :                : 
                              11335                 :                :     /* Search for comments associated with relation, using table */
 1346 tgl@sss.pgh.pa.us       11336                 :CBC          86 :     ncomments = findComments(tbinfo->dobj.catId.tableoid,
 7840                         11337                 :             86 :                              tbinfo->dobj.catId.oid,
                              11338                 :                :                              &comments);
                              11339                 :                : 
                              11340                 :                :     /* If comments exist, build COMMENT ON statements */
                              11341         [ -  + ]:             86 :     if (ncomments <= 0)
 7840 tgl@sss.pgh.pa.us       11342                 :UBC           0 :         return;
                              11343                 :                : 
 8520 tgl@sss.pgh.pa.us       11344                 :CBC          86 :     query = createPQExpBuffer();
 2749                         11345                 :             86 :     tag = createPQExpBuffer();
                              11346                 :                : 
 7840                         11347         [ +  + ]:            248 :     while (ncomments > 0)
                              11348                 :                :     {
                              11349                 :            162 :         const char *descr = comments->descr;
                              11350                 :            162 :         int         objsubid = comments->objsubid;
                              11351                 :                : 
 8520                         11352         [ +  + ]:            162 :         if (objsubid == 0)
                              11353                 :                :         {
 2749                         11354                 :             38 :             resetPQExpBuffer(tag);
                              11355                 :             38 :             appendPQExpBuffer(tag, "%s %s", reltypename,
 7857                         11356                 :             38 :                               fmtId(tbinfo->dobj.name));
                              11357                 :                : 
 8520                         11358                 :             38 :             resetPQExpBuffer(query);
 2749                         11359                 :             38 :             appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
                              11360                 :             38 :                               fmtQualifiedDumpable(tbinfo));
 7041                         11361                 :             38 :             appendStringLiteralAH(query, descr, fout);
 4310 heikki.linnakangas@i    11362                 :             38 :             appendPQExpBufferStr(query, ";\n");
                              11363                 :                : 
 7945 tgl@sss.pgh.pa.us       11364                 :             38 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    11365                 :             38 :                          ARCHIVE_OPTS(.tag = tag->data,
                              11366                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              11367                 :                :                                       .owner = tbinfo->rolname,
                              11368                 :                :                                       .description = "COMMENT",
                              11369                 :                :                                       .section = SECTION_NONE,
                              11370                 :                :                                       .createStmt = query->data,
                              11371                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              11372                 :                :                                       .nDeps = 1));
                              11373                 :                :         }
 8520 tgl@sss.pgh.pa.us       11374   [ +  -  +  - ]:            124 :         else if (objsubid > 0 && objsubid <= tbinfo->numatts)
                              11375                 :                :         {
 2749                         11376                 :            124 :             resetPQExpBuffer(tag);
                              11377                 :            124 :             appendPQExpBuffer(tag, "COLUMN %s.",
 7857                         11378                 :            124 :                               fmtId(tbinfo->dobj.name));
 2749                         11379                 :            124 :             appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
                              11380                 :                : 
 8520                         11381                 :            124 :             resetPQExpBuffer(query);
 2749                         11382                 :            124 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              11383                 :            124 :                               fmtQualifiedDumpable(tbinfo));
                              11384                 :            124 :             appendPQExpBuffer(query, "%s IS ",
                              11385                 :            124 :                               fmtId(tbinfo->attnames[objsubid - 1]));
 7041                         11386                 :            124 :             appendStringLiteralAH(query, descr, fout);
 4310 heikki.linnakangas@i    11387                 :            124 :             appendPQExpBufferStr(query, ";\n");
                              11388                 :                : 
 7945 tgl@sss.pgh.pa.us       11389                 :            124 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    11390                 :            124 :                          ARCHIVE_OPTS(.tag = tag->data,
                              11391                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              11392                 :                :                                       .owner = tbinfo->rolname,
                              11393                 :                :                                       .description = "COMMENT",
                              11394                 :                :                                       .section = SECTION_NONE,
                              11395                 :                :                                       .createStmt = query->data,
                              11396                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              11397                 :                :                                       .nDeps = 1));
                              11398                 :                :         }
                              11399                 :                : 
 7840 tgl@sss.pgh.pa.us       11400                 :            162 :         comments++;
                              11401                 :            162 :         ncomments--;
                              11402                 :                :     }
                              11403                 :                : 
 8800                         11404                 :             86 :     destroyPQExpBuffer(query);
 2749                         11405                 :             86 :     destroyPQExpBuffer(tag);
                              11406                 :                : }
                              11407                 :                : 
                              11408                 :                : /*
                              11409                 :                :  * findComments --
                              11410                 :                :  *
                              11411                 :                :  * Find the comment(s), if any, associated with the given object.  All the
                              11412                 :                :  * objsubid values associated with the given classoid/objoid are found with
                              11413                 :                :  * one search.
                              11414                 :                :  */
                              11415                 :                : static int
 1346                         11416                 :           6790 : findComments(Oid classoid, Oid objoid, CommentItem **items)
                              11417                 :                : {
 7840                         11418                 :           6790 :     CommentItem *middle = NULL;
                              11419                 :                :     CommentItem *low;
                              11420                 :                :     CommentItem *high;
                              11421                 :                :     int         nmatch;
                              11422                 :                : 
                              11423                 :                :     /*
                              11424                 :                :      * Do binary search to find some item matching the object.
                              11425                 :                :      */
                              11426                 :           6790 :     low = &comments[0];
 7678 bruce@momjian.us        11427                 :           6790 :     high = &comments[ncomments - 1];
 7840 tgl@sss.pgh.pa.us       11428         [ +  + ]:          67878 :     while (low <= high)
                              11429                 :                :     {
                              11430                 :          67831 :         middle = low + (high - low) / 2;
                              11431                 :                : 
                              11432         [ +  + ]:          67831 :         if (classoid < middle->classoid)
                              11433                 :           7763 :             high = middle - 1;
                              11434         [ +  + ]:          60068 :         else if (classoid > middle->classoid)
                              11435                 :           7326 :             low = middle + 1;
                              11436         [ +  + ]:          52742 :         else if (objoid < middle->objoid)
                              11437                 :          22411 :             high = middle - 1;
                              11438         [ +  + ]:          30331 :         else if (objoid > middle->objoid)
                              11439                 :          23588 :             low = middle + 1;
                              11440                 :                :         else
                              11441                 :           6743 :             break;              /* found a match */
                              11442                 :                :     }
                              11443                 :                : 
                              11444         [ +  + ]:           6790 :     if (low > high)              /* no matches */
                              11445                 :                :     {
                              11446                 :             47 :         *items = NULL;
                              11447                 :             47 :         return 0;
                              11448                 :                :     }
                              11449                 :                : 
                              11450                 :                :     /*
                              11451                 :                :      * Now determine how many items match the object.  The search loop
                              11452                 :                :      * invariant still holds: only items between low and high inclusive could
                              11453                 :                :      * match.
                              11454                 :                :      */
                              11455                 :           6743 :     nmatch = 1;
                              11456         [ +  + ]:           6819 :     while (middle > low)
                              11457                 :                :     {
                              11458         [ +  + ]:           3302 :         if (classoid != middle[-1].classoid ||
                              11459         [ +  + ]:           3123 :             objoid != middle[-1].objoid)
                              11460                 :                :             break;
 7840 tgl@sss.pgh.pa.us       11461                 :GBC          76 :         middle--;
                              11462                 :             76 :         nmatch++;
                              11463                 :                :     }
                              11464                 :                : 
 7840 tgl@sss.pgh.pa.us       11465                 :CBC        6743 :     *items = middle;
                              11466                 :                : 
                              11467                 :           6743 :     middle += nmatch;
                              11468         [ +  + ]:           6743 :     while (middle <= high)
                              11469                 :                :     {
                              11470         [ +  + ]:           3494 :         if (classoid != middle->classoid ||
                              11471         [ -  + ]:           3238 :             objoid != middle->objoid)
                              11472                 :                :             break;
 7840 tgl@sss.pgh.pa.us       11473                 :LBC        (76) :         middle++;
                              11474                 :           (76) :         nmatch++;
                              11475                 :                :     }
                              11476                 :                : 
 7840 tgl@sss.pgh.pa.us       11477                 :CBC        6743 :     return nmatch;
                              11478                 :                : }
                              11479                 :                : 
                              11480                 :                : /*
                              11481                 :                :  * collectComments --
                              11482                 :                :  *
                              11483                 :                :  * Construct a table of all comments available for database objects;
                              11484                 :                :  * also set the has-comment component flag for each relevant object.
                              11485                 :                :  *
                              11486                 :                :  * We used to do per-object queries for the comments, but it's much faster
                              11487                 :                :  * to pull them all over at once, and on most databases the memory cost
                              11488                 :                :  * isn't high.
                              11489                 :                :  *
                              11490                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              11491                 :                :  */
                              11492                 :                : static void
 1370                         11493                 :            185 : collectComments(Archive *fout)
                              11494                 :                : {
                              11495                 :                :     PGresult   *res;
                              11496                 :                :     PQExpBuffer query;
                              11497                 :                :     int         i_description;
                              11498                 :                :     int         i_classoid;
                              11499                 :                :     int         i_objoid;
                              11500                 :                :     int         i_objsubid;
                              11501                 :                :     int         ntups;
                              11502                 :                :     int         i;
                              11503                 :                :     DumpableObject *dobj;
                              11504                 :                : 
 7840                         11505                 :            185 :     query = createPQExpBuffer();
                              11506                 :                : 
 3251                         11507                 :            185 :     appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
                              11508                 :                :                          "FROM pg_catalog.pg_description "
                              11509                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              11510                 :                : 
 4960 rhaas@postgresql.org    11511                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11512                 :                : 
                              11513                 :                :     /* Construct lookup table containing OIDs in numeric form */
                              11514                 :                : 
 7840 tgl@sss.pgh.pa.us       11515                 :            185 :     i_description = PQfnumber(res, "description");
                              11516                 :            185 :     i_classoid = PQfnumber(res, "classoid");
                              11517                 :            185 :     i_objoid = PQfnumber(res, "objoid");
                              11518                 :            185 :     i_objsubid = PQfnumber(res, "objsubid");
                              11519                 :                : 
                              11520                 :            185 :     ntups = PQntuples(res);
                              11521                 :                : 
 5034 bruce@momjian.us        11522                 :            185 :     comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
 1370 tgl@sss.pgh.pa.us       11523                 :            185 :     ncomments = 0;
                              11524                 :            185 :     dobj = NULL;
                              11525                 :                : 
 7840                         11526         [ +  + ]:         993463 :     for (i = 0; i < ntups; i++)
                              11527                 :                :     {
                              11528                 :                :         CatalogId   objId;
                              11529                 :                :         int         subid;
                              11530                 :                : 
 1370                         11531                 :         993278 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              11532                 :         993278 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              11533                 :         993278 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              11534                 :                : 
                              11535                 :                :         /* We needn't remember comments that don't match any dumpable object */
                              11536         [ +  + ]:         993278 :         if (dobj == NULL ||
                              11537         [ +  + ]:         362930 :             dobj->catId.tableoid != objId.tableoid ||
                              11538         [ +  + ]:         360676 :             dobj->catId.oid != objId.oid)
                              11539                 :         993176 :             dobj = findObjectByCatalogId(objId);
                              11540         [ +  + ]:         993278 :         if (dobj == NULL)
                              11541                 :         630169 :             continue;
                              11542                 :                : 
                              11543                 :                :         /*
                              11544                 :                :          * Comments on columns of composite types are linked to the type's
                              11545                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
                              11546                 :                :          * in the type's own DumpableObject.
                              11547                 :                :          */
                              11548   [ +  +  +  - ]:         363109 :         if (subid != 0 && dobj->objType == DO_TABLE &&
                              11549         [ +  + ]:            218 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              11550                 :             51 :         {
                              11551                 :                :             TypeInfo   *cTypeInfo;
                              11552                 :                : 
                              11553                 :             51 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              11554         [ +  - ]:             51 :             if (cTypeInfo)
                              11555                 :             51 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                              11556                 :                :         }
                              11557                 :                :         else
                              11558                 :         363058 :             dobj->components |= DUMP_COMPONENT_COMMENT;
                              11559                 :                : 
                              11560                 :         363109 :         comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
                              11561                 :         363109 :         comments[ncomments].classoid = objId.tableoid;
                              11562                 :         363109 :         comments[ncomments].objoid = objId.oid;
                              11563                 :         363109 :         comments[ncomments].objsubid = subid;
                              11564                 :         363109 :         ncomments++;
                              11565                 :                :     }
                              11566                 :                : 
                              11567                 :            185 :     PQclear(res);
 7840                         11568                 :            185 :     destroyPQExpBuffer(query);
                              11569                 :            185 : }
                              11570                 :                : 
                              11571                 :                : /*
                              11572                 :                :  * dumpDumpableObject
                              11573                 :                :  *
                              11574                 :                :  * This routine and its subsidiaries are responsible for creating
                              11575                 :                :  * ArchiveEntries (TOC objects) for each object to be dumped.
                              11576                 :                :  */
                              11577                 :                : static void
 1370                         11578                 :         819195 : dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                              11579                 :                : {
                              11580                 :                :     /*
                              11581                 :                :      * Clear any dump-request bits for components that don't exist for this
                              11582                 :                :      * object.  (This makes it safe to initially use DUMP_COMPONENT_ALL as the
                              11583                 :                :      * request for every kind of object.)
                              11584                 :                :      */
                              11585                 :         819195 :     dobj->dump &= dobj->components;
                              11586                 :                : 
                              11587                 :                :     /* Now, short-circuit if there's nothing to be done here. */
                              11588         [ +  + ]:         819195 :     if (dobj->dump == 0)
                              11589                 :         738209 :         return;
                              11590                 :                : 
 7945                         11591   [ +  +  +  +  :          80986 :     switch (dobj->objType)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                        +  +  +  - ]
                              11592                 :                :     {
                              11593                 :            495 :         case DO_NAMESPACE:
 1669 peter@eisentraut.org    11594                 :            495 :             dumpNamespace(fout, (const NamespaceInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11595                 :            495 :             break;
 5324                         11596                 :             19 :         case DO_EXTENSION:
 1669 peter@eisentraut.org    11597                 :             19 :             dumpExtension(fout, (const ExtensionInfo *) dobj);
 5324 tgl@sss.pgh.pa.us       11598                 :             19 :             break;
 7945                         11599                 :            968 :         case DO_TYPE:
 1669 peter@eisentraut.org    11600                 :            968 :             dumpType(fout, (const TypeInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11601                 :            968 :             break;
 7128                         11602                 :             79 :         case DO_SHELL_TYPE:
 1669 peter@eisentraut.org    11603                 :             79 :             dumpShellType(fout, (const ShellTypeInfo *) dobj);
 7128 tgl@sss.pgh.pa.us       11604                 :             79 :             break;
 7945                         11605                 :           1873 :         case DO_FUNC:
 1669 peter@eisentraut.org    11606                 :           1873 :             dumpFunc(fout, (const FuncInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11607                 :           1873 :             break;
                              11608                 :            298 :         case DO_AGG:
 1669 peter@eisentraut.org    11609                 :            298 :             dumpAgg(fout, (const AggInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11610                 :            298 :             break;
                              11611                 :           2510 :         case DO_OPERATOR:
 1669 peter@eisentraut.org    11612                 :           2510 :             dumpOpr(fout, (const OprInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11613                 :           2510 :             break;
 3454 alvherre@alvh.no-ip.    11614                 :             92 :         case DO_ACCESS_METHOD:
 1669 peter@eisentraut.org    11615                 :             92 :             dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
 3454 alvherre@alvh.no-ip.    11616                 :             92 :             break;
 7945 tgl@sss.pgh.pa.us       11617                 :            678 :         case DO_OPCLASS:
 1669 peter@eisentraut.org    11618                 :            678 :             dumpOpclass(fout, (const OpclassInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11619                 :            678 :             break;
 6801                         11620                 :            561 :         case DO_OPFAMILY:
 1669 peter@eisentraut.org    11621                 :            561 :             dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
 6801 tgl@sss.pgh.pa.us       11622                 :            561 :             break;
 5320 peter_e@gmx.net         11623                 :           4655 :         case DO_COLLATION:
 1669 peter@eisentraut.org    11624                 :           4655 :             dumpCollation(fout, (const CollInfo *) dobj);
 5320 peter_e@gmx.net         11625                 :           4655 :             break;
 7945 tgl@sss.pgh.pa.us       11626                 :            428 :         case DO_CONVERSION:
 1669 peter@eisentraut.org    11627                 :            428 :             dumpConversion(fout, (const ConvInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11628                 :            428 :             break;
                              11629                 :          31135 :         case DO_TABLE:
 1669 peter@eisentraut.org    11630                 :          31135 :             dumpTable(fout, (const TableInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11631                 :          31135 :             break;
 1699                         11632                 :           1435 :         case DO_TABLE_ATTACH:
 1669 peter@eisentraut.org    11633                 :           1435 :             dumpTableAttach(fout, (const TableAttachInfo *) dobj);
 1699 tgl@sss.pgh.pa.us       11634                 :           1435 :             break;
 7945                         11635                 :           1104 :         case DO_ATTRDEF:
 1669 peter@eisentraut.org    11636                 :           1104 :             dumpAttrDef(fout, (const AttrDefInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11637                 :           1104 :             break;
                              11638                 :           2688 :         case DO_INDEX:
 1669 peter@eisentraut.org    11639                 :           2688 :             dumpIndex(fout, (const IndxInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11640                 :           2688 :             break;
 2787 alvherre@alvh.no-ip.    11641                 :            612 :         case DO_INDEX_ATTACH:
 1669 peter@eisentraut.org    11642                 :            612 :             dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
 2787 alvherre@alvh.no-ip.    11643                 :            612 :             break;
 3088                         11644                 :            151 :         case DO_STATSEXT:
 1669 peter@eisentraut.org    11645                 :            151 :             dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
 3088 alvherre@alvh.no-ip.    11646                 :            151 :             break;
 4570 kgrittn@postgresql.o    11647                 :            432 :         case DO_REFRESH_MATVIEW:
 1669 peter@eisentraut.org    11648                 :            432 :             refreshMatViewData(fout, (const TableDataInfo *) dobj);
 4570 kgrittn@postgresql.o    11649                 :            432 :             break;
 7945 tgl@sss.pgh.pa.us       11650                 :           1223 :         case DO_RULE:
 1669 peter@eisentraut.org    11651                 :           1223 :             dumpRule(fout, (const RuleInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11652                 :           1223 :             break;
                              11653                 :            553 :         case DO_TRIGGER:
 1669 peter@eisentraut.org    11654                 :            553 :             dumpTrigger(fout, (const TriggerInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11655                 :            553 :             break;
 4798 rhaas@postgresql.org    11656                 :             48 :         case DO_EVENT_TRIGGER:
 1669 peter@eisentraut.org    11657                 :             48 :             dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
 4798 rhaas@postgresql.org    11658                 :             48 :             break;
 7945 tgl@sss.pgh.pa.us       11659                 :           2462 :         case DO_CONSTRAINT:
 1669 peter@eisentraut.org    11660                 :           2462 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11661                 :           2462 :             break;
                              11662                 :            183 :         case DO_FK_CONSTRAINT:
 1669 peter@eisentraut.org    11663                 :            183 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11664                 :            183 :             break;
                              11665                 :             94 :         case DO_PROCLANG:
 1669 peter@eisentraut.org    11666                 :             94 :             dumpProcLang(fout, (const ProcLangInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11667                 :             94 :             break;
                              11668                 :             73 :         case DO_CAST:
 1669 peter@eisentraut.org    11669                 :             73 :             dumpCast(fout, (const CastInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11670                 :             73 :             break;
 3786 peter_e@gmx.net         11671                 :             48 :         case DO_TRANSFORM:
 1669 peter@eisentraut.org    11672                 :             48 :             dumpTransform(fout, (const TransformInfo *) dobj);
 3786 peter_e@gmx.net         11673                 :             48 :             break;
 3301                         11674                 :            411 :         case DO_SEQUENCE_SET:
 1669 peter@eisentraut.org    11675                 :            411 :             dumpSequenceData(fout, (const TableDataInfo *) dobj);
 3301 peter_e@gmx.net         11676                 :            411 :             break;
 7945 tgl@sss.pgh.pa.us       11677                 :           4496 :         case DO_TABLE_DATA:
 1669 peter@eisentraut.org    11678                 :           4496 :             dumpTableData(fout, (const TableDataInfo *) dobj);
 7945 tgl@sss.pgh.pa.us       11679                 :           4496 :             break;
 6075                         11680                 :          14929 :         case DO_DUMMY_TYPE:
                              11681                 :                :             /* table rowtypes and array types are never dumped separately */
 7857                         11682                 :          14929 :             break;
 6591                         11683                 :             47 :         case DO_TSPARSER:
 1669 peter@eisentraut.org    11684                 :             47 :             dumpTSParser(fout, (const TSParserInfo *) dobj);
 6591 tgl@sss.pgh.pa.us       11685                 :             47 :             break;
                              11686                 :            179 :         case DO_TSDICT:
 1669 peter@eisentraut.org    11687                 :            179 :             dumpTSDictionary(fout, (const TSDictInfo *) dobj);
 6591 tgl@sss.pgh.pa.us       11688                 :            179 :             break;
                              11689                 :             59 :         case DO_TSTEMPLATE:
 1669 peter@eisentraut.org    11690                 :             59 :             dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
 6591 tgl@sss.pgh.pa.us       11691                 :             59 :             break;
                              11692                 :            154 :         case DO_TSCONFIG:
 1669 peter@eisentraut.org    11693                 :            154 :             dumpTSConfig(fout, (const TSConfigInfo *) dobj);
 6591 tgl@sss.pgh.pa.us       11694                 :            154 :             break;
 6105 peter_e@gmx.net         11695                 :             58 :         case DO_FDW:
 1669 peter@eisentraut.org    11696                 :             58 :             dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
 6105 peter_e@gmx.net         11697                 :             58 :             break;
                              11698                 :             62 :         case DO_FOREIGN_SERVER:
 1669 peter@eisentraut.org    11699                 :             62 :             dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
 6105 peter_e@gmx.net         11700                 :             62 :             break;
 5815 tgl@sss.pgh.pa.us       11701                 :            184 :         case DO_DEFAULT_ACL:
 1669 peter@eisentraut.org    11702                 :            184 :             dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
 5815 tgl@sss.pgh.pa.us       11703                 :            184 :             break;
 1006 peter@eisentraut.org    11704                 :             84 :         case DO_LARGE_OBJECT:
                              11705                 :             84 :             dumpLO(fout, (const LoInfo *) dobj);
 5679 tgl@sss.pgh.pa.us       11706                 :             84 :             break;
 1006 peter@eisentraut.org    11707                 :             85 :         case DO_LARGE_OBJECT_DATA:
 3440 sfrost@snowman.net      11708         [ +  - ]:             85 :             if (dobj->dump & DUMP_COMPONENT_DATA)
                              11709                 :                :             {
                              11710                 :                :                 LoInfo     *loinfo;
                              11711                 :                :                 TocEntry   *te;
                              11712                 :                : 
  523 tgl@sss.pgh.pa.us       11713                 :             85 :                 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
                              11714         [ -  + ]:             85 :                 if (loinfo == NULL)
  523 tgl@sss.pgh.pa.us       11715                 :UBC           0 :                     pg_fatal("missing metadata for large objects \"%s\"",
                              11716                 :                :                              dobj->name);
                              11717                 :                : 
 2549 tgl@sss.pgh.pa.us       11718                 :CBC          85 :                 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
 2409 alvherre@alvh.no-ip.    11719                 :             85 :                                   ARCHIVE_OPTS(.tag = dobj->name,
                              11720                 :                :                                                .owner = loinfo->rolname,
                              11721                 :                :                                                .description = "BLOBS",
                              11722                 :                :                                                .section = SECTION_DATA,
                              11723                 :                :                                                .deps = dobj->dependencies,
                              11724                 :                :                                                .nDeps = dobj->nDeps,
                              11725                 :                :                                                .dumpFn = dumpLOs,
                              11726                 :                :                                                .dumpArg = loinfo));
                              11727                 :                : 
                              11728                 :                :                 /*
                              11729                 :                :                  * Set the TocEntry's dataLength in case we are doing a
                              11730                 :                :                  * parallel dump and want to order dump jobs by table size.
                              11731                 :                :                  * (We need some size estimate for every TocEntry with a
                              11732                 :                :                  * DataDumper function.)  We don't currently have any cheap
                              11733                 :                :                  * way to estimate the size of LOs, but fortunately it doesn't
                              11734                 :                :                  * matter too much as long as we get large batches of LOs
                              11735                 :                :                  * processed reasonably early.  Assume 8K per blob.
                              11736                 :                :                  */
  523 tgl@sss.pgh.pa.us       11737                 :             85 :                 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
                              11738                 :                :             }
 7857                         11739                 :             85 :             break;
 3936 sfrost@snowman.net      11740                 :            368 :         case DO_POLICY:
 1669 peter@eisentraut.org    11741                 :            368 :             dumpPolicy(fout, (const PolicyInfo *) dobj);
 4005 sfrost@snowman.net      11742                 :            368 :             break;
 3152 peter_e@gmx.net         11743                 :            241 :         case DO_PUBLICATION:
 1669 peter@eisentraut.org    11744                 :            241 :             dumpPublication(fout, (const PublicationInfo *) dobj);
 3152 peter_e@gmx.net         11745                 :            241 :             break;
                              11746                 :            326 :         case DO_PUBLICATION_REL:
 1669 peter@eisentraut.org    11747                 :            326 :             dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
 3152 peter_e@gmx.net         11748                 :            326 :             break;
 1397 akapila@postgresql.o    11749                 :            111 :         case DO_PUBLICATION_TABLE_IN_SCHEMA:
 1410                         11750                 :            111 :             dumpPublicationNamespace(fout,
                              11751                 :                :                                      (const PublicationSchemaInfo *) dobj);
                              11752                 :            111 :             break;
 3152 peter_e@gmx.net         11753                 :            131 :         case DO_SUBSCRIPTION:
 1669 peter@eisentraut.org    11754                 :            131 :             dumpSubscription(fout, (const SubscriptionInfo *) dobj);
 3152 peter_e@gmx.net         11755                 :            131 :             break;
  613 akapila@postgresql.o    11756                 :              2 :         case DO_SUBSCRIPTION_REL:
                              11757                 :              2 :             dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
                              11758                 :              2 :             break;
  198 jdavis@postgresql.or    11759                 :           3792 :         case DO_REL_STATS:
                              11760                 :           3792 :             dumpRelationStats(fout, (const RelStatsInfo *) dobj);
                              11761                 :           3792 :             break;
 4821 tgl@sss.pgh.pa.us       11762                 :            370 :         case DO_PRE_DATA_BOUNDARY:
                              11763                 :                :         case DO_POST_DATA_BOUNDARY:
                              11764                 :                :             /* never dumped, nothing to do */
                              11765                 :            370 :             break;
                              11766                 :                :     }
                              11767                 :                : }
                              11768                 :                : 
                              11769                 :                : /*
                              11770                 :                :  * dumpNamespace
                              11771                 :                :  *    writes out to fout the queries to recreate a user-defined namespace
                              11772                 :                :  */
                              11773                 :                : static void
 1669 peter@eisentraut.org    11774                 :            495 : dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
                              11775                 :                : {
 3524 tgl@sss.pgh.pa.us       11776                 :            495 :     DumpOptions *dopt = fout->dopt;
                              11777                 :                :     PQExpBuffer q;
                              11778                 :                :     PQExpBuffer delq;
                              11779                 :                :     char       *qnspname;
                              11780                 :                : 
                              11781                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    11782         [ +  + ]:            495 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       11783                 :             28 :         return;
                              11784                 :                : 
                              11785                 :            467 :     q = createPQExpBuffer();
                              11786                 :            467 :     delq = createPQExpBuffer();
                              11787                 :                : 
 5034 bruce@momjian.us        11788                 :            467 :     qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
                              11789                 :                : 
 1531 noah@leadboat.com       11790         [ +  + ]:            467 :     if (nspinfo->create)
                              11791                 :                :     {
                              11792                 :            317 :         appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
                              11793                 :            317 :         appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
                              11794                 :                :     }
                              11795                 :                :     else
                              11796                 :                :     {
                              11797                 :                :         /* see selectDumpableNamespace() */
                              11798                 :            150 :         appendPQExpBufferStr(delq,
                              11799                 :                :                              "-- *not* dropping schema, since initdb creates it\n");
                              11800                 :            150 :         appendPQExpBufferStr(q,
                              11801                 :                :                              "-- *not* creating schema, since initdb creates it\n");
                              11802                 :                :     }
                              11803                 :                : 
 3980 alvherre@alvh.no-ip.    11804         [ +  + ]:            467 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       11805                 :             90 :         binary_upgrade_extension_member(q, &nspinfo->dobj,
                              11806                 :                :                                         "SCHEMA", qnspname, NULL);
                              11807                 :                : 
 3440 sfrost@snowman.net      11808         [ +  + ]:            467 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11809                 :            203 :         ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    11810                 :            203 :                      ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
                              11811                 :                :                                   .owner = nspinfo->rolname,
                              11812                 :                :                                   .description = "SCHEMA",
                              11813                 :                :                                   .section = SECTION_PRE_DATA,
                              11814                 :                :                                   .createStmt = q->data,
                              11815                 :                :                                   .dropStmt = delq->data));
                              11816                 :                : 
                              11817                 :                :     /* Dump Schema Comments and Security Labels */
 3440 sfrost@snowman.net      11818         [ +  + ]:            467 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              11819                 :                :     {
 1531 noah@leadboat.com       11820                 :            155 :         const char *initdb_comment = NULL;
                              11821                 :                : 
                              11822   [ +  +  +  + ]:            155 :         if (!nspinfo->create && strcmp(qnspname, "public") == 0)
 1362 tgl@sss.pgh.pa.us       11823                 :            116 :             initdb_comment = "standard public schema";
 1531 noah@leadboat.com       11824                 :            155 :         dumpCommentExtended(fout, "SCHEMA", qnspname,
                              11825                 :            155 :                             NULL, nspinfo->rolname,
                              11826                 :            155 :                             nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
                              11827                 :                :                             initdb_comment);
                              11828                 :                :     }
                              11829                 :                : 
 3440 sfrost@snowman.net      11830         [ -  + ]:            467 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       11831                 :UBC           0 :         dumpSecLabel(fout, "SCHEMA", qnspname,
 3440 sfrost@snowman.net      11832                 :              0 :                      NULL, nspinfo->rolname,
                              11833                 :              0 :                      nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
                              11834                 :                : 
 3440 sfrost@snowman.net      11835         [ +  + ]:CBC         467 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       11836                 :            359 :         dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
                              11837                 :                :                 qnspname, NULL, NULL,
  523                         11838                 :            359 :                 NULL, nspinfo->rolname, &nspinfo->dacl);
                              11839                 :                : 
 7945                         11840                 :            467 :     free(qnspname);
                              11841                 :                : 
 8520                         11842                 :            467 :     destroyPQExpBuffer(q);
                              11843                 :            467 :     destroyPQExpBuffer(delq);
                              11844                 :                : }
                              11845                 :                : 
                              11846                 :                : /*
                              11847                 :                :  * dumpExtension
                              11848                 :                :  *    writes out to fout the queries to recreate an extension
                              11849                 :                :  */
                              11850                 :                : static void
 1669 peter@eisentraut.org    11851                 :             19 : dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
                              11852                 :                : {
 3524 tgl@sss.pgh.pa.us       11853                 :             19 :     DumpOptions *dopt = fout->dopt;
                              11854                 :                :     PQExpBuffer q;
                              11855                 :                :     PQExpBuffer delq;
                              11856                 :                :     char       *qextname;
                              11857                 :                : 
                              11858                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    11859         [ +  + ]:             19 :     if (!dopt->dumpSchema)
 5324 tgl@sss.pgh.pa.us       11860                 :              1 :         return;
                              11861                 :                : 
                              11862                 :             18 :     q = createPQExpBuffer();
                              11863                 :             18 :     delq = createPQExpBuffer();
                              11864                 :                : 
 5034 bruce@momjian.us        11865                 :             18 :     qextname = pg_strdup(fmtId(extinfo->dobj.name));
                              11866                 :                : 
 5324 tgl@sss.pgh.pa.us       11867                 :             18 :     appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
                              11868                 :                : 
 3980 alvherre@alvh.no-ip.    11869         [ +  + ]:             18 :     if (!dopt->binary_upgrade)
                              11870                 :                :     {
                              11871                 :                :         /*
                              11872                 :                :          * In a regular dump, we simply create the extension, intentionally
                              11873                 :                :          * not specifying a version, so that the destination installation's
                              11874                 :                :          * default version is used.
                              11875                 :                :          *
                              11876                 :                :          * Use of IF NOT EXISTS here is unlike our behavior for other object
                              11877                 :                :          * types; but there are various scenarios in which it's convenient to
                              11878                 :                :          * manually create the desired extension before restoring, so we
                              11879                 :                :          * prefer to allow it to exist already.
                              11880                 :                :          */
 5300 tgl@sss.pgh.pa.us       11881                 :             17 :         appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
 5323                         11882                 :             17 :                           qextname, fmtId(extinfo->namespace));
                              11883                 :                :     }
                              11884                 :                :     else
                              11885                 :                :     {
                              11886                 :                :         /*
                              11887                 :                :          * In binary-upgrade mode, it's critical to reproduce the state of the
                              11888                 :                :          * database exactly, so our procedure is to create an empty extension,
                              11889                 :                :          * restore all the contained objects normally, and add them to the
                              11890                 :                :          * extension one by one.  This function performs just the first of
                              11891                 :                :          * those steps.  binary_upgrade_extension_member() takes care of
                              11892                 :                :          * adding member objects as they're created.
                              11893                 :                :          */
                              11894                 :                :         int         i;
                              11895                 :                :         int         n;
                              11896                 :                : 
 4310 heikki.linnakangas@i    11897                 :              1 :         appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
                              11898                 :                : 
                              11899                 :                :         /*
                              11900                 :                :          * We unconditionally create the extension, so we must drop it if it
                              11901                 :                :          * exists.  This could happen if the user deleted 'plpgsql' and then
                              11902                 :                :          * readded it, causing its oid to be greater than g_last_builtin_oid.
                              11903                 :                :          */
 4812 bruce@momjian.us        11904                 :              1 :         appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
                              11905                 :                : 
 4310 heikki.linnakangas@i    11906                 :              1 :         appendPQExpBufferStr(q,
                              11907                 :                :                              "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
 5323 tgl@sss.pgh.pa.us       11908                 :              1 :         appendStringLiteralAH(q, extinfo->dobj.name, fout);
 4310 heikki.linnakangas@i    11909                 :              1 :         appendPQExpBufferStr(q, ", ");
 5323 tgl@sss.pgh.pa.us       11910                 :              1 :         appendStringLiteralAH(q, extinfo->namespace, fout);
 4310 heikki.linnakangas@i    11911                 :              1 :         appendPQExpBufferStr(q, ", ");
 5323 tgl@sss.pgh.pa.us       11912         [ +  - ]:              1 :         appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
 5321                         11913                 :              1 :         appendStringLiteralAH(q, extinfo->extversion, fout);
 4310 heikki.linnakangas@i    11914                 :              1 :         appendPQExpBufferStr(q, ", ");
                              11915                 :                : 
                              11916                 :                :         /*
                              11917                 :                :          * Note that we're pushing extconfig (an OID array) back into
                              11918                 :                :          * pg_extension exactly as-is.  This is OK because pg_class OIDs are
                              11919                 :                :          * preserved in binary upgrade.
                              11920                 :                :          */
 5323 tgl@sss.pgh.pa.us       11921         [ +  - ]:              1 :         if (strlen(extinfo->extconfig) > 2)
                              11922                 :              1 :             appendStringLiteralAH(q, extinfo->extconfig, fout);
                              11923                 :                :         else
 4310 heikki.linnakangas@i    11924                 :UBC           0 :             appendPQExpBufferStr(q, "NULL");
 4310 heikki.linnakangas@i    11925                 :CBC           1 :         appendPQExpBufferStr(q, ", ");
 5323 tgl@sss.pgh.pa.us       11926         [ +  - ]:              1 :         if (strlen(extinfo->extcondition) > 2)
                              11927                 :              1 :             appendStringLiteralAH(q, extinfo->extcondition, fout);
                              11928                 :                :         else
 4310 heikki.linnakangas@i    11929                 :UBC           0 :             appendPQExpBufferStr(q, "NULL");
 4310 heikki.linnakangas@i    11930                 :CBC           1 :         appendPQExpBufferStr(q, ", ");
                              11931                 :              1 :         appendPQExpBufferStr(q, "ARRAY[");
 5323 tgl@sss.pgh.pa.us       11932                 :              1 :         n = 0;
                              11933         [ +  + ]:              2 :         for (i = 0; i < extinfo->dobj.nDeps; i++)
                              11934                 :                :         {
                              11935                 :                :             DumpableObject *extobj;
                              11936                 :                : 
                              11937                 :              1 :             extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
                              11938   [ +  -  -  + ]:              1 :             if (extobj && extobj->objType == DO_EXTENSION)
                              11939                 :                :             {
 5323 tgl@sss.pgh.pa.us       11940         [ #  # ]:UBC           0 :                 if (n++ > 0)
 4310 heikki.linnakangas@i    11941                 :              0 :                     appendPQExpBufferChar(q, ',');
 5323 tgl@sss.pgh.pa.us       11942                 :              0 :                 appendStringLiteralAH(q, extobj->name, fout);
                              11943                 :                :             }
                              11944                 :                :         }
 4310 heikki.linnakangas@i    11945                 :CBC           1 :         appendPQExpBufferStr(q, "]::pg_catalog.text[]");
                              11946                 :              1 :         appendPQExpBufferStr(q, ");\n");
                              11947                 :                :     }
                              11948                 :                : 
 3440 sfrost@snowman.net      11949         [ +  - ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11950                 :             18 :         ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    11951                 :             18 :                      ARCHIVE_OPTS(.tag = extinfo->dobj.name,
                              11952                 :                :                                   .description = "EXTENSION",
                              11953                 :                :                                   .section = SECTION_PRE_DATA,
                              11954                 :                :                                   .createStmt = q->data,
                              11955                 :                :                                   .dropStmt = delq->data));
                              11956                 :                : 
                              11957                 :                :     /* Dump Extension Comments and Security Labels */
 3440 sfrost@snowman.net      11958         [ +  - ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       11959                 :             18 :         dumpComment(fout, "EXTENSION", qextname,
                              11960                 :                :                     NULL, "",
 3440 sfrost@snowman.net      11961                 :             18 :                     extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
                              11962                 :                : 
                              11963         [ -  + ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       11964                 :UBC           0 :         dumpSecLabel(fout, "EXTENSION", qextname,
                              11965                 :                :                      NULL, "",
 3440 sfrost@snowman.net      11966                 :              0 :                      extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
                              11967                 :                : 
 5324 tgl@sss.pgh.pa.us       11968                 :CBC          18 :     free(qextname);
                              11969                 :                : 
                              11970                 :             18 :     destroyPQExpBuffer(q);
                              11971                 :             18 :     destroyPQExpBuffer(delq);
                              11972                 :                : }
                              11973                 :                : 
                              11974                 :                : /*
                              11975                 :                :  * dumpType
                              11976                 :                :  *    writes out to fout the queries to recreate a user-defined type
                              11977                 :                :  */
                              11978                 :                : static void
 1669 peter@eisentraut.org    11979                 :            968 : dumpType(Archive *fout, const TypeInfo *tyinfo)
                              11980                 :                : {
 3524 tgl@sss.pgh.pa.us       11981                 :            968 :     DumpOptions *dopt = fout->dopt;
                              11982                 :                : 
                              11983                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    11984         [ +  + ]:            968 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       11985                 :             49 :         return;
                              11986                 :                : 
                              11987                 :                :     /* Dump out in proper style */
 5736 bruce@momjian.us        11988         [ +  + ]:            919 :     if (tyinfo->typtype == TYPTYPE_BASE)
 3524 tgl@sss.pgh.pa.us       11989                 :            286 :         dumpBaseType(fout, tyinfo);
 5736 bruce@momjian.us        11990         [ +  + ]:            633 :     else if (tyinfo->typtype == TYPTYPE_DOMAIN)
 3524 tgl@sss.pgh.pa.us       11991                 :            158 :         dumpDomain(fout, tyinfo);
 5736 bruce@momjian.us        11992         [ +  + ]:            475 :     else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
 3524 tgl@sss.pgh.pa.us       11993                 :            136 :         dumpCompositeType(fout, tyinfo);
 5736 bruce@momjian.us        11994         [ +  + ]:            339 :     else if (tyinfo->typtype == TYPTYPE_ENUM)
 3524 tgl@sss.pgh.pa.us       11995                 :             97 :         dumpEnumType(fout, tyinfo);
 5056 heikki.linnakangas@i    11996         [ +  + ]:            242 :     else if (tyinfo->typtype == TYPTYPE_RANGE)
 3524 tgl@sss.pgh.pa.us       11997                 :            124 :         dumpRangeType(fout, tyinfo);
 3686                         11998   [ +  -  +  + ]:            118 :     else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
 3524                         11999                 :             43 :         dumpUndefinedType(fout, tyinfo);
                              12000                 :                :     else
 2350 peter@eisentraut.org    12001                 :             75 :         pg_log_warning("typtype of data type \"%s\" appears to be invalid",
                              12002                 :                :                        tyinfo->dobj.name);
                              12003                 :                : }
                              12004                 :                : 
                              12005                 :                : /*
                              12006                 :                :  * dumpEnumType
                              12007                 :                :  *    writes out to fout the queries to recreate a user-defined enum type
                              12008                 :                :  */
                              12009                 :                : static void
 1669                         12010                 :             97 : dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
                              12011                 :                : {
 3524 tgl@sss.pgh.pa.us       12012                 :             97 :     DumpOptions *dopt = fout->dopt;
 6732                         12013                 :             97 :     PQExpBuffer q = createPQExpBuffer();
                              12014                 :             97 :     PQExpBuffer delq = createPQExpBuffer();
                              12015                 :             97 :     PQExpBuffer query = createPQExpBuffer();
                              12016                 :                :     PGresult   *res;
                              12017                 :                :     int         num,
                              12018                 :                :                 i;
                              12019                 :                :     Oid         enum_oid;
                              12020                 :                :     char       *qtypname;
                              12021                 :                :     char       *qualtypname;
                              12022                 :                :     char       *label;
                              12023                 :                :     int         i_enumlabel;
                              12024                 :                :     int         i_oid;
                              12025                 :                : 
 1370                         12026         [ +  + ]:             97 :     if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
                              12027                 :                :     {
                              12028                 :                :         /* Set up query for enum-specific details */
                              12029                 :             46 :         appendPQExpBufferStr(query,
                              12030                 :                :                              "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
                              12031                 :                :                              "SELECT oid, enumlabel "
                              12032                 :                :                              "FROM pg_catalog.pg_enum "
                              12033                 :                :                              "WHERE enumtypid = $1 "
                              12034                 :                :                              "ORDER BY enumsortorder");
                              12035                 :                : 
                              12036                 :             46 :         ExecuteSqlStatement(fout, query->data);
                              12037                 :                : 
                              12038                 :             46 :         fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
                              12039                 :                :     }
                              12040                 :                : 
                              12041                 :             97 :     printfPQExpBuffer(query,
                              12042                 :                :                       "EXECUTE dumpEnumType('%u')",
                              12043                 :             97 :                       tyinfo->dobj.catId.oid);
                              12044                 :                : 
 4960 rhaas@postgresql.org    12045                 :             97 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              12046                 :                : 
 6732 tgl@sss.pgh.pa.us       12047                 :             97 :     num = PQntuples(res);
                              12048                 :                : 
 4654                         12049                 :             97 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12050                 :             97 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12051                 :                : 
                              12052                 :                :     /*
                              12053                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              12054                 :                :      * functions are generic and do not get dropped.
                              12055                 :                :      */
                              12056                 :             97 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12057                 :                : 
 3980 alvherre@alvh.no-ip.    12058         [ +  + ]:             97 :     if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    12059                 :              6 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2898 tgl@sss.pgh.pa.us       12060                 :              6 :                                                  tyinfo->dobj.catId.oid,
                              12061                 :                :                                                  false, false);
                              12062                 :                : 
 5732 bruce@momjian.us        12063                 :             97 :     appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
                              12064                 :                :                       qualtypname);
                              12065                 :                : 
 3980 alvherre@alvh.no-ip.    12066         [ +  + ]:             97 :     if (!dopt->binary_upgrade)
                              12067                 :                :     {
 1471 dgustafsson@postgres    12068                 :             91 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              12069                 :                : 
                              12070                 :                :         /* Labels with server-assigned oids */
 5732 bruce@momjian.us        12071         [ +  + ]:            530 :         for (i = 0; i < num; i++)
                              12072                 :                :         {
 1471 dgustafsson@postgres    12073                 :            439 :             label = PQgetvalue(res, i, i_enumlabel);
 5732 bruce@momjian.us        12074         [ +  + ]:            439 :             if (i > 0)
 4310 heikki.linnakangas@i    12075                 :            348 :                 appendPQExpBufferChar(q, ',');
                              12076                 :            439 :             appendPQExpBufferStr(q, "\n    ");
 5732 bruce@momjian.us        12077                 :            439 :             appendStringLiteralAH(q, label, fout);
                              12078                 :                :         }
                              12079                 :                :     }
                              12080                 :                : 
 4310 heikki.linnakangas@i    12081                 :             97 :     appendPQExpBufferStr(q, "\n);\n");
                              12082                 :                : 
 3980 alvherre@alvh.no-ip.    12083         [ +  + ]:             97 :     if (dopt->binary_upgrade)
                              12084                 :                :     {
 1471 dgustafsson@postgres    12085                 :              6 :         i_oid = PQfnumber(res, "oid");
                              12086                 :              6 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              12087                 :                : 
                              12088                 :                :         /* Labels with dump-assigned (preserved) oids */
 5732 bruce@momjian.us        12089         [ +  + ]:             62 :         for (i = 0; i < num; i++)
                              12090                 :                :         {
 1471 dgustafsson@postgres    12091                 :             56 :             enum_oid = atooid(PQgetvalue(res, i, i_oid));
                              12092                 :             56 :             label = PQgetvalue(res, i, i_enumlabel);
                              12093                 :                : 
 5732 bruce@momjian.us        12094         [ +  + ]:             56 :             if (i == 0)
 4310 heikki.linnakangas@i    12095                 :              6 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
 5732 bruce@momjian.us        12096                 :             56 :             appendPQExpBuffer(q,
                              12097                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                              12098                 :                :                               enum_oid);
 2749 tgl@sss.pgh.pa.us       12099                 :             56 :             appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
 5732 bruce@momjian.us        12100                 :             56 :             appendStringLiteralAH(q, label, fout);
 4310 heikki.linnakangas@i    12101                 :             56 :             appendPQExpBufferStr(q, ";\n\n");
                              12102                 :                :         }
                              12103                 :                :     }
                              12104                 :                : 
 3980 alvherre@alvh.no-ip.    12105         [ +  + ]:             97 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       12106                 :              6 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12107                 :                :                                         "TYPE", qtypname,
                              12108                 :              6 :                                         tyinfo->dobj.namespace->dobj.name);
                              12109                 :                : 
 3440 sfrost@snowman.net      12110         [ +  - ]:             97 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12111                 :             97 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    12112                 :             97 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12113                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12114                 :                :                                   .owner = tyinfo->rolname,
                              12115                 :                :                                   .description = "TYPE",
                              12116                 :                :                                   .section = SECTION_PRE_DATA,
                              12117                 :                :                                   .createStmt = q->data,
                              12118                 :                :                                   .dropStmt = delq->data));
                              12119                 :                : 
                              12120                 :                :     /* Dump Type Comments and Security Labels */
 3440 sfrost@snowman.net      12121         [ +  + ]:             97 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       12122                 :             38 :         dumpComment(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12123                 :             38 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12124                 :             38 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12125                 :                : 
                              12126         [ -  + ]:             97 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       12127                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12128                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12129                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12130                 :                : 
 3440 sfrost@snowman.net      12131         [ +  + ]:CBC          97 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       12132                 :             38 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12133                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      12134                 :             38 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       12135                 :             38 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12136                 :                : 
 5056 heikki.linnakangas@i    12137                 :             97 :     PQclear(res);
                              12138                 :             97 :     destroyPQExpBuffer(q);
                              12139                 :             97 :     destroyPQExpBuffer(delq);
                              12140                 :             97 :     destroyPQExpBuffer(query);
 2749 tgl@sss.pgh.pa.us       12141                 :             97 :     free(qtypname);
                              12142                 :             97 :     free(qualtypname);
 5056 heikki.linnakangas@i    12143                 :             97 : }
                              12144                 :                : 
                              12145                 :                : /*
                              12146                 :                :  * dumpRangeType
                              12147                 :                :  *    writes out to fout the queries to recreate a user-defined range type
                              12148                 :                :  */
                              12149                 :                : static void
 1669 peter@eisentraut.org    12150                 :            124 : dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
                              12151                 :                : {
 3524 tgl@sss.pgh.pa.us       12152                 :            124 :     DumpOptions *dopt = fout->dopt;
 5056 heikki.linnakangas@i    12153                 :            124 :     PQExpBuffer q = createPQExpBuffer();
                              12154                 :            124 :     PQExpBuffer delq = createPQExpBuffer();
                              12155                 :            124 :     PQExpBuffer query = createPQExpBuffer();
                              12156                 :                :     PGresult   *res;
                              12157                 :                :     Oid         collationOid;
                              12158                 :                :     char       *qtypname;
                              12159                 :                :     char       *qualtypname;
                              12160                 :                :     char       *procname;
                              12161                 :                : 
 1370 tgl@sss.pgh.pa.us       12162         [ +  + ]:            124 :     if (!fout->is_prepared[PREPQUERY_DUMPRANGETYPE])
                              12163                 :                :     {
                              12164                 :                :         /* Set up query for range-specific details */
                              12165                 :             46 :         appendPQExpBufferStr(query,
                              12166                 :                :                              "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
                              12167                 :                : 
                              12168                 :             46 :         appendPQExpBufferStr(query,
                              12169                 :                :                              "SELECT ");
                              12170                 :                : 
                              12171         [ +  - ]:             46 :         if (fout->remoteVersion >= 140000)
                              12172                 :             46 :             appendPQExpBufferStr(query,
                              12173                 :                :                                  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
                              12174                 :                :         else
 1370 tgl@sss.pgh.pa.us       12175                 :UBC           0 :             appendPQExpBufferStr(query,
                              12176                 :                :                                  "NULL AS rngmultitype, ");
                              12177                 :                : 
 1370 tgl@sss.pgh.pa.us       12178                 :CBC          46 :         appendPQExpBufferStr(query,
                              12179                 :                :                              "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                              12180                 :                :                              "opc.opcname AS opcname, "
                              12181                 :                :                              "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
                              12182                 :                :                              "  WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
                              12183                 :                :                              "opc.opcdefault, "
                              12184                 :                :                              "CASE WHEN rngcollation = st.typcollation THEN 0 "
                              12185                 :                :                              "     ELSE rngcollation END AS collation, "
                              12186                 :                :                              "rngcanonical, rngsubdiff "
                              12187                 :                :                              "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
                              12188                 :                :                              "     pg_catalog.pg_opclass opc "
                              12189                 :                :                              "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
                              12190                 :                :                              "rngtypid = $1");
                              12191                 :                : 
                              12192                 :             46 :         ExecuteSqlStatement(fout, query->data);
                              12193                 :                : 
                              12194                 :             46 :         fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
                              12195                 :                :     }
                              12196                 :                : 
                              12197                 :            124 :     printfPQExpBuffer(query,
                              12198                 :                :                       "EXECUTE dumpRangeType('%u')",
 5056 heikki.linnakangas@i    12199                 :            124 :                       tyinfo->dobj.catId.oid);
                              12200                 :                : 
 4951 rhaas@postgresql.org    12201                 :            124 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12202                 :                : 
 4654 tgl@sss.pgh.pa.us       12203                 :            124 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12204                 :            124 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12205                 :                : 
                              12206                 :                :     /*
                              12207                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              12208                 :                :      * functions are generic and do not get dropped.
                              12209                 :                :      */
                              12210                 :            124 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12211                 :                : 
 3980 alvherre@alvh.no-ip.    12212         [ +  + ]:            124 :     if (dopt->binary_upgrade)
 2898 tgl@sss.pgh.pa.us       12213                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              12214                 :              8 :                                                  tyinfo->dobj.catId.oid,
                              12215                 :                :                                                  false, true);
                              12216                 :                : 
 5056 heikki.linnakangas@i    12217                 :            124 :     appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
                              12218                 :                :                       qualtypname);
                              12219                 :                : 
 5039 tgl@sss.pgh.pa.us       12220                 :            124 :     appendPQExpBuffer(q, "\n    subtype = %s",
                              12221                 :                :                       PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
                              12222                 :                : 
 1721 akorotkov@postgresql    12223         [ +  - ]:            124 :     if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
                              12224                 :            124 :         appendPQExpBuffer(q, ",\n    multirange_type_name = %s",
                              12225                 :                :                           PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
                              12226                 :                : 
                              12227                 :                :     /* print subtype_opclass only if not default for subtype */
 5039 tgl@sss.pgh.pa.us       12228         [ +  + ]:            124 :     if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
                              12229                 :                :     {
 4836 bruce@momjian.us        12230                 :             38 :         char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
                              12231                 :             38 :         char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
                              12232                 :                : 
 5039 tgl@sss.pgh.pa.us       12233                 :             38 :         appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                              12234                 :                :                           fmtId(nspname));
 4310 heikki.linnakangas@i    12235                 :             38 :         appendPQExpBufferStr(q, fmtId(opcname));
                              12236                 :                :     }
                              12237                 :                : 
 5039 tgl@sss.pgh.pa.us       12238                 :            124 :     collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
 5056 heikki.linnakangas@i    12239         [ +  + ]:            124 :     if (OidIsValid(collationOid))
                              12240                 :                :     {
 5039 tgl@sss.pgh.pa.us       12241                 :             43 :         CollInfo   *coll = findCollationByOid(collationOid);
                              12242                 :                : 
 5056 heikki.linnakangas@i    12243         [ +  - ]:             43 :         if (coll)
 2749 tgl@sss.pgh.pa.us       12244                 :             43 :             appendPQExpBuffer(q, ",\n    collation = %s",
                              12245                 :             43 :                               fmtQualifiedDumpable(coll));
                              12246                 :                :     }
                              12247                 :                : 
 5039                         12248                 :            124 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
                              12249         [ +  + ]:            124 :     if (strcmp(procname, "-") != 0)
                              12250                 :              9 :         appendPQExpBuffer(q, ",\n    canonical = %s", procname);
                              12251                 :                : 
                              12252                 :            124 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
                              12253         [ +  + ]:            124 :     if (strcmp(procname, "-") != 0)
                              12254                 :             23 :         appendPQExpBuffer(q, ",\n    subtype_diff = %s", procname);
                              12255                 :                : 
 4310 heikki.linnakangas@i    12256                 :            124 :     appendPQExpBufferStr(q, "\n);\n");
                              12257                 :                : 
 3980 alvherre@alvh.no-ip.    12258         [ +  + ]:            124 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       12259                 :              8 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12260                 :                :                                         "TYPE", qtypname,
                              12261                 :              8 :                                         tyinfo->dobj.namespace->dobj.name);
                              12262                 :                : 
 3440 sfrost@snowman.net      12263         [ +  - ]:            124 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12264                 :            124 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    12265                 :            124 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12266                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12267                 :                :                                   .owner = tyinfo->rolname,
                              12268                 :                :                                   .description = "TYPE",
                              12269                 :                :                                   .section = SECTION_PRE_DATA,
                              12270                 :                :                                   .createStmt = q->data,
                              12271                 :                :                                   .dropStmt = delq->data));
                              12272                 :                : 
                              12273                 :                :     /* Dump Type Comments and Security Labels */
 3440 sfrost@snowman.net      12274         [ +  + ]:            124 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       12275                 :             56 :         dumpComment(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12276                 :             56 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12277                 :             56 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12278                 :                : 
                              12279         [ -  + ]:            124 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       12280                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12281                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12282                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12283                 :                : 
 3440 sfrost@snowman.net      12284         [ +  + ]:CBC         124 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       12285                 :             38 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12286                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      12287                 :             38 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       12288                 :             38 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12289                 :                : 
 6732                         12290                 :            124 :     PQclear(res);
                              12291                 :            124 :     destroyPQExpBuffer(q);
                              12292                 :            124 :     destroyPQExpBuffer(delq);
                              12293                 :            124 :     destroyPQExpBuffer(query);
 2749                         12294                 :            124 :     free(qtypname);
                              12295                 :            124 :     free(qualtypname);
 7945                         12296                 :            124 : }
                              12297                 :                : 
                              12298                 :                : /*
                              12299                 :                :  * dumpUndefinedType
                              12300                 :                :  *    writes out to fout the queries to recreate a !typisdefined type
                              12301                 :                :  *
                              12302                 :                :  * This is a shell type, but we use different terminology to distinguish
                              12303                 :                :  * this case from where we have to emit a shell type definition to break
                              12304                 :                :  * circular dependencies.  An undefined type shouldn't ever have anything
                              12305                 :                :  * depending on it.
                              12306                 :                :  */
                              12307                 :                : static void
 1669 peter@eisentraut.org    12308                 :             43 : dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
                              12309                 :                : {
 3524 tgl@sss.pgh.pa.us       12310                 :             43 :     DumpOptions *dopt = fout->dopt;
 3686                         12311                 :             43 :     PQExpBuffer q = createPQExpBuffer();
                              12312                 :             43 :     PQExpBuffer delq = createPQExpBuffer();
                              12313                 :                :     char       *qtypname;
                              12314                 :                :     char       *qualtypname;
                              12315                 :                : 
                              12316                 :             43 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12317                 :             43 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12318                 :                : 
                              12319                 :             43 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12320                 :                : 
 3686                         12321         [ +  + ]:             43 :     if (dopt->binary_upgrade)
 2898                         12322                 :              2 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              12323                 :              2 :                                                  tyinfo->dobj.catId.oid,
                              12324                 :                :                                                  false, false);
                              12325                 :                : 
 3686                         12326                 :             43 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
                              12327                 :                :                       qualtypname);
                              12328                 :                : 
                              12329         [ +  + ]:             43 :     if (dopt->binary_upgrade)
 2749                         12330                 :              2 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12331                 :                :                                         "TYPE", qtypname,
                              12332                 :              2 :                                         tyinfo->dobj.namespace->dobj.name);
                              12333                 :                : 
 3440 sfrost@snowman.net      12334         [ +  - ]:             43 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12335                 :             43 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    12336                 :             43 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12337                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12338                 :                :                                   .owner = tyinfo->rolname,
                              12339                 :                :                                   .description = "TYPE",
                              12340                 :                :                                   .section = SECTION_PRE_DATA,
                              12341                 :                :                                   .createStmt = q->data,
                              12342                 :                :                                   .dropStmt = delq->data));
                              12343                 :                : 
                              12344                 :                :     /* Dump Type Comments and Security Labels */
 3440 sfrost@snowman.net      12345         [ +  + ]:             43 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       12346                 :             38 :         dumpComment(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12347                 :             38 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12348                 :             38 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12349                 :                : 
                              12350         [ -  + ]:             43 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       12351                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12352                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12353                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12354                 :                : 
 3440 sfrost@snowman.net      12355         [ -  + ]:CBC          43 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       12356                 :UBC           0 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12357                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      12358                 :              0 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       12359                 :              0 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12360                 :                : 
 3686 tgl@sss.pgh.pa.us       12361                 :CBC          43 :     destroyPQExpBuffer(q);
                              12362                 :             43 :     destroyPQExpBuffer(delq);
 2749                         12363                 :             43 :     free(qtypname);
                              12364                 :             43 :     free(qualtypname);
 3686                         12365                 :             43 : }
                              12366                 :                : 
                              12367                 :                : /*
                              12368                 :                :  * dumpBaseType
                              12369                 :                :  *    writes out to fout the queries to recreate a user-defined base type
                              12370                 :                :  */
                              12371                 :                : static void
 1669 peter@eisentraut.org    12372                 :            286 : dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
                              12373                 :                : {
 3524 tgl@sss.pgh.pa.us       12374                 :            286 :     DumpOptions *dopt = fout->dopt;
 8520                         12375                 :            286 :     PQExpBuffer q = createPQExpBuffer();
                              12376                 :            286 :     PQExpBuffer delq = createPQExpBuffer();
                              12377                 :            286 :     PQExpBuffer query = createPQExpBuffer();
                              12378                 :                :     PGresult   *res;
                              12379                 :                :     char       *qtypname;
                              12380                 :                :     char       *qualtypname;
                              12381                 :                :     char       *typlen;
                              12382                 :                :     char       *typinput;
                              12383                 :                :     char       *typoutput;
                              12384                 :                :     char       *typreceive;
                              12385                 :                :     char       *typsend;
                              12386                 :                :     char       *typmodin;
                              12387                 :                :     char       *typmodout;
                              12388                 :                :     char       *typanalyze;
                              12389                 :                :     char       *typsubscript;
                              12390                 :                :     Oid         typreceiveoid;
                              12391                 :                :     Oid         typsendoid;
                              12392                 :                :     Oid         typmodinoid;
                              12393                 :                :     Oid         typmodoutoid;
                              12394                 :                :     Oid         typanalyzeoid;
                              12395                 :                :     Oid         typsubscriptoid;
                              12396                 :                :     char       *typcategory;
                              12397                 :                :     char       *typispreferred;
                              12398                 :                :     char       *typdelim;
                              12399                 :                :     char       *typbyval;
                              12400                 :                :     char       *typalign;
                              12401                 :                :     char       *typstorage;
                              12402                 :                :     char       *typcollatable;
                              12403                 :                :     char       *typdefault;
 7137                         12404                 :            286 :     bool        typdefault_is_literal = false;
                              12405                 :                : 
 1370                         12406         [ +  + ]:            286 :     if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
                              12407                 :                :     {
                              12408                 :                :         /* Set up query for type-specific details */
 1735                         12409                 :             46 :         appendPQExpBufferStr(query,
                              12410                 :                :                              "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
                              12411                 :                :                              "SELECT typlen, "
                              12412                 :                :                              "typinput, typoutput, typreceive, typsend, "
                              12413                 :                :                              "typreceive::pg_catalog.oid AS typreceiveoid, "
                              12414                 :                :                              "typsend::pg_catalog.oid AS typsendoid, "
                              12415                 :                :                              "typanalyze, "
                              12416                 :                :                              "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                              12417                 :                :                              "typdelim, typbyval, typalign, typstorage, "
                              12418                 :                :                              "typmodin, typmodout, "
                              12419                 :                :                              "typmodin::pg_catalog.oid AS typmodinoid, "
                              12420                 :                :                              "typmodout::pg_catalog.oid AS typmodoutoid, "
                              12421                 :                :                              "typcategory, typispreferred, "
                              12422                 :                :                              "(typcollation <> 0) AS typcollatable, "
                              12423                 :                :                              "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
                              12424                 :                : 
 1370                         12425         [ +  - ]:             46 :         if (fout->remoteVersion >= 140000)
                              12426                 :             46 :             appendPQExpBufferStr(query,
                              12427                 :                :                                  "typsubscript, "
                              12428                 :                :                                  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
                              12429                 :                :         else
 1370 tgl@sss.pgh.pa.us       12430                 :UBC           0 :             appendPQExpBufferStr(query,
                              12431                 :                :                                  "'-' AS typsubscript, 0 AS typsubscriptoid ");
                              12432                 :                : 
 1370 tgl@sss.pgh.pa.us       12433                 :CBC          46 :         appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
                              12434                 :                :                              "WHERE oid = $1");
                              12435                 :                : 
                              12436                 :             46 :         ExecuteSqlStatement(fout, query->data);
                              12437                 :                : 
                              12438                 :             46 :         fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
                              12439                 :                :     }
                              12440                 :                : 
                              12441                 :            286 :     printfPQExpBuffer(query,
                              12442                 :                :                       "EXECUTE dumpBaseType('%u')",
 1735                         12443                 :            286 :                       tyinfo->dobj.catId.oid);
                              12444                 :                : 
 4951 rhaas@postgresql.org    12445                 :            286 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12446                 :                : 
 8520 tgl@sss.pgh.pa.us       12447                 :            286 :     typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
                              12448                 :            286 :     typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
                              12449                 :            286 :     typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
 8157                         12450                 :            286 :     typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
                              12451                 :            286 :     typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
 6825                         12452                 :            286 :     typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
                              12453                 :            286 :     typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
 7877                         12454                 :            286 :     typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
 1732                         12455                 :            286 :     typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
 7945                         12456                 :            286 :     typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
                              12457                 :            286 :     typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
 6825                         12458                 :            286 :     typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
                              12459                 :            286 :     typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
 7877                         12460                 :            286 :     typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
 1732                         12461                 :            286 :     typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
 6247                         12462                 :            286 :     typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
                              12463                 :            286 :     typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
 8520                         12464                 :            286 :     typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
                              12465                 :            286 :     typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
                              12466                 :            286 :     typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
                              12467                 :            286 :     typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
 5303 peter_e@gmx.net         12468                 :            286 :     typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
 7137 tgl@sss.pgh.pa.us       12469         [ -  + ]:            286 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
 7137 tgl@sss.pgh.pa.us       12470                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
 7137 tgl@sss.pgh.pa.us       12471         [ +  + ]:CBC         286 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              12472                 :                :     {
                              12473                 :             48 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6912 bruce@momjian.us        12474                 :             48 :         typdefault_is_literal = true;   /* it needs quotes */
                              12475                 :                :     }
                              12476                 :                :     else
 7137 tgl@sss.pgh.pa.us       12477                 :            238 :         typdefault = NULL;
                              12478                 :                : 
 4654                         12479                 :            286 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12480                 :            286 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12481                 :                : 
                              12482                 :                :     /*
                              12483                 :                :      * The reason we include CASCADE is that the circular dependency between
                              12484                 :                :      * the type and its I/O functions makes it impossible to drop the type any
                              12485                 :                :      * other way.
                              12486                 :                :      */
                              12487                 :            286 :     appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
                              12488                 :                : 
                              12489                 :                :     /*
                              12490                 :                :      * We might already have a shell type, but setting pg_type_oid is
                              12491                 :                :      * harmless, and in any case we'd better set the array type OID.
                              12492                 :                :      */
 3980 alvherre@alvh.no-ip.    12493         [ +  + ]:            286 :     if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    12494                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2898 tgl@sss.pgh.pa.us       12495                 :              8 :                                                  tyinfo->dobj.catId.oid,
                              12496                 :                :                                                  false, false);
                              12497                 :                : 
 8520                         12498                 :            286 :     appendPQExpBuffer(q,
                              12499                 :                :                       "CREATE TYPE %s (\n"
                              12500                 :                :                       "    INTERNALLENGTH = %s",
                              12501                 :                :                       qualtypname,
 8445 peter_e@gmx.net         12502         [ +  + ]:            286 :                       (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
                              12503                 :                : 
                              12504                 :                :     /* regproc result is sufficiently quoted already */
 3251 tgl@sss.pgh.pa.us       12505                 :            286 :     appendPQExpBuffer(q, ",\n    INPUT = %s", typinput);
                              12506                 :            286 :     appendPQExpBuffer(q, ",\n    OUTPUT = %s", typoutput);
                              12507         [ +  + ]:            286 :     if (OidIsValid(typreceiveoid))
                              12508                 :            207 :         appendPQExpBuffer(q, ",\n    RECEIVE = %s", typreceive);
                              12509         [ +  + ]:            286 :     if (OidIsValid(typsendoid))
                              12510                 :            207 :         appendPQExpBuffer(q, ",\n    SEND = %s", typsend);
                              12511         [ +  + ]:            286 :     if (OidIsValid(typmodinoid))
                              12512                 :             35 :         appendPQExpBuffer(q, ",\n    TYPMOD_IN = %s", typmodin);
                              12513         [ +  + ]:            286 :     if (OidIsValid(typmodoutoid))
                              12514                 :             35 :         appendPQExpBuffer(q, ",\n    TYPMOD_OUT = %s", typmodout);
                              12515         [ +  + ]:            286 :     if (OidIsValid(typanalyzeoid))
                              12516                 :              3 :         appendPQExpBuffer(q, ",\n    ANALYZE = %s", typanalyze);
                              12517                 :                : 
 5303 peter_e@gmx.net         12518         [ +  + ]:            286 :     if (strcmp(typcollatable, "t") == 0)
 4310 heikki.linnakangas@i    12519                 :             30 :         appendPQExpBufferStr(q, ",\n    COLLATABLE = true");
                              12520                 :                : 
 8520 tgl@sss.pgh.pa.us       12521         [ +  + ]:            286 :     if (typdefault != NULL)
                              12522                 :                :     {
 4310 heikki.linnakangas@i    12523                 :             48 :         appendPQExpBufferStr(q, ",\n    DEFAULT = ");
 7137 tgl@sss.pgh.pa.us       12524         [ +  - ]:             48 :         if (typdefault_is_literal)
 7041                         12525                 :             48 :             appendStringLiteralAH(q, typdefault, fout);
                              12526                 :                :         else
 7137 tgl@sss.pgh.pa.us       12527                 :UBC           0 :             appendPQExpBufferStr(q, typdefault);
                              12528                 :                :     }
                              12529                 :                : 
 1732 tgl@sss.pgh.pa.us       12530         [ +  + ]:CBC         286 :     if (OidIsValid(typsubscriptoid))
                              12531                 :             29 :         appendPQExpBuffer(q, ",\n    SUBSCRIPT = %s", typsubscript);
                              12532                 :                : 
 5736 bruce@momjian.us        12533         [ +  + ]:            286 :     if (OidIsValid(tyinfo->typelem))
 1459 tgl@sss.pgh.pa.us       12534                 :             26 :         appendPQExpBuffer(q, ",\n    ELEMENT = %s",
                              12535                 :             26 :                           getFormattedTypeName(fout, tyinfo->typelem,
                              12536                 :                :                                                zeroIsError));
                              12537                 :                : 
 6247                         12538         [ +  + ]:            286 :     if (strcmp(typcategory, "U") != 0)
                              12539                 :                :     {
 4310 heikki.linnakangas@i    12540                 :            158 :         appendPQExpBufferStr(q, ",\n    CATEGORY = ");
 6247 tgl@sss.pgh.pa.us       12541                 :            158 :         appendStringLiteralAH(q, typcategory, fout);
                              12542                 :                :     }
                              12543                 :                : 
                              12544         [ +  + ]:            286 :     if (strcmp(typispreferred, "t") == 0)
 4310 heikki.linnakangas@i    12545                 :             29 :         appendPQExpBufferStr(q, ",\n    PREFERRED = true");
                              12546                 :                : 
 8157 tgl@sss.pgh.pa.us       12547   [ +  -  +  + ]:            286 :     if (typdelim && strcmp(typdelim, ",") != 0)
                              12548                 :                :     {
 4310 heikki.linnakangas@i    12549                 :              3 :         appendPQExpBufferStr(q, ",\n    DELIMITER = ");
 7041 tgl@sss.pgh.pa.us       12550                 :              3 :         appendStringLiteralAH(q, typdelim, fout);
                              12551                 :                :     }
                              12552                 :                : 
 2012                         12553         [ +  + ]:            286 :     if (*typalign == TYPALIGN_CHAR)
 4310 heikki.linnakangas@i    12554                 :             12 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = char");
 2012 tgl@sss.pgh.pa.us       12555         [ +  + ]:            274 :     else if (*typalign == TYPALIGN_SHORT)
 4310 heikki.linnakangas@i    12556                 :              6 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int2");
 2012 tgl@sss.pgh.pa.us       12557         [ +  + ]:            268 :     else if (*typalign == TYPALIGN_INT)
 4310 heikki.linnakangas@i    12558                 :            193 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int4");
 2012 tgl@sss.pgh.pa.us       12559         [ +  - ]:             75 :     else if (*typalign == TYPALIGN_DOUBLE)
 4310 heikki.linnakangas@i    12560                 :             75 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = double");
                              12561                 :                : 
 2012 tgl@sss.pgh.pa.us       12562         [ +  + ]:            286 :     if (*typstorage == TYPSTORAGE_PLAIN)
 4310 heikki.linnakangas@i    12563                 :            211 :         appendPQExpBufferStr(q, ",\n    STORAGE = plain");
 2012 tgl@sss.pgh.pa.us       12564         [ -  + ]:             75 :     else if (*typstorage == TYPSTORAGE_EXTERNAL)
 4310 heikki.linnakangas@i    12565                 :UBC           0 :         appendPQExpBufferStr(q, ",\n    STORAGE = external");
 2012 tgl@sss.pgh.pa.us       12566         [ +  + ]:CBC          75 :     else if (*typstorage == TYPSTORAGE_EXTENDED)
 4310 heikki.linnakangas@i    12567                 :             66 :         appendPQExpBufferStr(q, ",\n    STORAGE = extended");
 2012 tgl@sss.pgh.pa.us       12568         [ +  - ]:              9 :     else if (*typstorage == TYPSTORAGE_MAIN)
 4310 heikki.linnakangas@i    12569                 :              9 :         appendPQExpBufferStr(q, ",\n    STORAGE = main");
                              12570                 :                : 
 8520 tgl@sss.pgh.pa.us       12571         [ +  + ]:            286 :     if (strcmp(typbyval, "t") == 0)
 4310 heikki.linnakangas@i    12572                 :            140 :         appendPQExpBufferStr(q, ",\n    PASSEDBYVALUE");
                              12573                 :                : 
                              12574                 :            286 :     appendPQExpBufferStr(q, "\n);\n");
                              12575                 :                : 
 3980 alvherre@alvh.no-ip.    12576         [ +  + ]:            286 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       12577                 :              8 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12578                 :                :                                         "TYPE", qtypname,
                              12579                 :              8 :                                         tyinfo->dobj.namespace->dobj.name);
                              12580                 :                : 
 3440 sfrost@snowman.net      12581         [ +  - ]:            286 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12582                 :            286 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    12583                 :            286 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12584                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12585                 :                :                                   .owner = tyinfo->rolname,
                              12586                 :                :                                   .description = "TYPE",
                              12587                 :                :                                   .section = SECTION_PRE_DATA,
                              12588                 :                :                                   .createStmt = q->data,
                              12589                 :                :                                   .dropStmt = delq->data));
                              12590                 :                : 
                              12591                 :                :     /* Dump Type Comments and Security Labels */
 3440 sfrost@snowman.net      12592         [ +  + ]:            286 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       12593                 :            251 :         dumpComment(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12594                 :            251 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12595                 :            251 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12596                 :                : 
                              12597         [ -  + ]:            286 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       12598                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      12599                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12600                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12601                 :                : 
 3440 sfrost@snowman.net      12602         [ +  + ]:CBC         286 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       12603                 :             38 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12604                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      12605                 :             38 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       12606                 :             38 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12607                 :                : 
 9363 bruce@momjian.us        12608                 :            286 :     PQclear(res);
 8520 tgl@sss.pgh.pa.us       12609                 :            286 :     destroyPQExpBuffer(q);
                              12610                 :            286 :     destroyPQExpBuffer(delq);
 8800                         12611                 :            286 :     destroyPQExpBuffer(query);
 2749                         12612                 :            286 :     free(qtypname);
                              12613                 :            286 :     free(qualtypname);
 9363 bruce@momjian.us        12614                 :            286 : }
                              12615                 :                : 
                              12616                 :                : /*
                              12617                 :                :  * dumpDomain
                              12618                 :                :  *    writes out to fout the queries to recreate a user-defined domain
                              12619                 :                :  */
                              12620                 :                : static void
 1669 peter@eisentraut.org    12621                 :            158 : dumpDomain(Archive *fout, const TypeInfo *tyinfo)
                              12622                 :                : {
 3524 tgl@sss.pgh.pa.us       12623                 :            158 :     DumpOptions *dopt = fout->dopt;
 8555 bruce@momjian.us        12624                 :            158 :     PQExpBuffer q = createPQExpBuffer();
                              12625                 :            158 :     PQExpBuffer delq = createPQExpBuffer();
                              12626                 :            158 :     PQExpBuffer query = createPQExpBuffer();
                              12627                 :                :     PGresult   *res;
                              12628                 :                :     int         i;
                              12629                 :                :     char       *qtypname;
                              12630                 :                :     char       *qualtypname;
                              12631                 :                :     char       *typnotnull;
                              12632                 :                :     char       *typdefn;
                              12633                 :                :     char       *typdefault;
                              12634                 :                :     Oid         typcollation;
 7137 tgl@sss.pgh.pa.us       12635                 :            158 :     bool        typdefault_is_literal = false;
                              12636                 :                : 
 1370                         12637         [ +  + ]:            158 :     if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
                              12638                 :                :     {
                              12639                 :                :         /* Set up query for domain-specific details */
                              12640                 :             43 :         appendPQExpBufferStr(query,
                              12641                 :                :                              "PREPARE dumpDomain(pg_catalog.oid) AS\n");
                              12642                 :                : 
 1362                         12643                 :             43 :         appendPQExpBufferStr(query, "SELECT t.typnotnull, "
                              12644                 :                :                              "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
                              12645                 :                :                              "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
                              12646                 :                :                              "t.typdefault, "
                              12647                 :                :                              "CASE WHEN t.typcollation <> u.typcollation "
                              12648                 :                :                              "THEN t.typcollation ELSE 0 END AS typcollation "
                              12649                 :                :                              "FROM pg_catalog.pg_type t "
                              12650                 :                :                              "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
                              12651                 :                :                              "WHERE t.oid = $1");
                              12652                 :                : 
 1370                         12653                 :             43 :         ExecuteSqlStatement(fout, query->data);
                              12654                 :                : 
                              12655                 :             43 :         fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
                              12656                 :                :     }
                              12657                 :                : 
                              12658                 :            158 :     printfPQExpBuffer(query,
                              12659                 :                :                       "EXECUTE dumpDomain('%u')",
                              12660                 :            158 :                       tyinfo->dobj.catId.oid);
                              12661                 :                : 
 4951 rhaas@postgresql.org    12662                 :            158 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12663                 :                : 
 8520 tgl@sss.pgh.pa.us       12664                 :            158 :     typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
                              12665                 :            158 :     typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
 7137                         12666         [ +  + ]:            158 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
                              12667                 :             43 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
                              12668         [ -  + ]:            115 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              12669                 :                :     {
 8502 tgl@sss.pgh.pa.us       12670                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6912 bruce@momjian.us        12671                 :              0 :         typdefault_is_literal = true;   /* it needs quotes */
                              12672                 :                :     }
                              12673                 :                :     else
 7137 tgl@sss.pgh.pa.us       12674                 :CBC         115 :         typdefault = NULL;
 5294                         12675                 :            158 :     typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
                              12676                 :                : 
 3980 alvherre@alvh.no-ip.    12677         [ +  + ]:            158 :     if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    12678                 :             25 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2898 tgl@sss.pgh.pa.us       12679                 :             25 :                                                  tyinfo->dobj.catId.oid,
                              12680                 :                :                                                  true,  /* force array type */
                              12681                 :                :                                                  false);    /* force multirange type */
                              12682                 :                : 
 4654                         12683                 :            158 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12684                 :            158 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12685                 :                : 
 8555 bruce@momjian.us        12686                 :            158 :     appendPQExpBuffer(q,
                              12687                 :                :                       "CREATE DOMAIN %s AS %s",
                              12688                 :                :                       qualtypname,
                              12689                 :                :                       typdefn);
                              12690                 :                : 
                              12691                 :                :     /* Print collation only if different from base type's collation */
 5294 tgl@sss.pgh.pa.us       12692         [ +  + ]:            158 :     if (OidIsValid(typcollation))
                              12693                 :                :     {
                              12694                 :                :         CollInfo   *coll;
                              12695                 :                : 
                              12696                 :             38 :         coll = findCollationByOid(typcollation);
                              12697         [ +  - ]:             38 :         if (coll)
 2749                         12698                 :             38 :             appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
                              12699                 :                :     }
                              12700                 :                : 
                              12701                 :                :     /*
                              12702                 :                :      * Print a not-null constraint if there's one.  In servers older than 17
                              12703                 :                :      * these don't have names, so just print it unadorned; in newer ones they
                              12704                 :                :      * do, but most of the time it's going to be the standard generated one,
                              12705                 :                :      * so omit the name in that case also.
                              12706                 :                :      */
 8520                         12707         [ +  + ]:            158 :     if (typnotnull[0] == 't')
                              12708                 :                :     {
   47 alvherre@kurilemu.de    12709   [ +  -  -  + ]:             53 :         if (fout->remoteVersion < 170000 || tyinfo->notnull == NULL)
   47 alvherre@kurilemu.de    12710                 :UBC           0 :             appendPQExpBufferStr(q, " NOT NULL");
                              12711                 :                :         else
                              12712                 :                :         {
   47 alvherre@kurilemu.de    12713                 :CBC          53 :             ConstraintInfo *notnull = tyinfo->notnull;
                              12714                 :                : 
                              12715         [ +  - ]:             53 :             if (!notnull->separate)
                              12716                 :                :             {
                              12717                 :                :                 char       *default_name;
                              12718                 :                : 
                              12719                 :                :                 /* XXX should match ChooseConstraintName better */
                              12720                 :             53 :                 default_name = psprintf("%s_not_null", tyinfo->dobj.name);
                              12721                 :                : 
                              12722         [ +  + ]:             53 :                 if (strcmp(default_name, notnull->dobj.name) == 0)
                              12723                 :             15 :                     appendPQExpBufferStr(q, " NOT NULL");
                              12724                 :                :                 else
                              12725                 :             38 :                     appendPQExpBuffer(q, " CONSTRAINT %s %s",
                              12726                 :             38 :                                       fmtId(notnull->dobj.name), notnull->condef);
                              12727                 :             53 :                 free(default_name);
                              12728                 :                :             }
                              12729                 :                :         }
                              12730                 :                :     }
                              12731                 :                : 
 7137 tgl@sss.pgh.pa.us       12732         [ +  + ]:            158 :     if (typdefault != NULL)
                              12733                 :                :     {
 4310 heikki.linnakangas@i    12734                 :             43 :         appendPQExpBufferStr(q, " DEFAULT ");
 7137 tgl@sss.pgh.pa.us       12735         [ -  + ]:             43 :         if (typdefault_is_literal)
 7041 tgl@sss.pgh.pa.us       12736                 :UBC           0 :             appendStringLiteralAH(q, typdefault, fout);
                              12737                 :                :         else
 7137 tgl@sss.pgh.pa.us       12738                 :CBC          43 :             appendPQExpBufferStr(q, typdefault);
                              12739                 :                :     }
                              12740                 :                : 
 8304                         12741                 :            158 :     PQclear(res);
                              12742                 :                : 
                              12743                 :                :     /*
                              12744                 :                :      * Add any CHECK constraints for the domain
                              12745                 :                :      */
 5736 bruce@momjian.us        12746         [ +  + ]:            271 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              12747                 :                :     {
                              12748                 :            113 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
                              12749                 :                : 
   47 alvherre@kurilemu.de    12750   [ +  +  +  - ]:            113 :         if (!domcheck->separate && domcheck->contype == 'c')
 7945 tgl@sss.pgh.pa.us       12751                 :            108 :             appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
 7266 bruce@momjian.us        12752                 :            108 :                               fmtId(domcheck->dobj.name), domcheck->condef);
                              12753                 :                :     }
                              12754                 :                : 
 4310 heikki.linnakangas@i    12755                 :            158 :     appendPQExpBufferStr(q, ";\n");
                              12756                 :                : 
 2749 tgl@sss.pgh.pa.us       12757                 :            158 :     appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
                              12758                 :                : 
 3980 alvherre@alvh.no-ip.    12759         [ +  + ]:            158 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       12760                 :             25 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12761                 :                :                                         "DOMAIN", qtypname,
                              12762                 :             25 :                                         tyinfo->dobj.namespace->dobj.name);
                              12763                 :                : 
 3440 sfrost@snowman.net      12764         [ +  - ]:            158 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12765                 :            158 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    12766                 :            158 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              12767                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              12768                 :                :                                   .owner = tyinfo->rolname,
                              12769                 :                :                                   .description = "DOMAIN",
                              12770                 :                :                                   .section = SECTION_PRE_DATA,
                              12771                 :                :                                   .createStmt = q->data,
                              12772                 :                :                                   .dropStmt = delq->data));
                              12773                 :                : 
                              12774                 :                :     /* Dump Domain Comments and Security Labels */
 3440 sfrost@snowman.net      12775         [ -  + ]:            158 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       12776                 :UBC           0 :         dumpComment(fout, "DOMAIN", qtypname,
 3440 sfrost@snowman.net      12777                 :              0 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12778                 :              0 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12779                 :                : 
 3440 sfrost@snowman.net      12780         [ -  + ]:CBC         158 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       12781                 :UBC           0 :         dumpSecLabel(fout, "DOMAIN", qtypname,
 3440 sfrost@snowman.net      12782                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              12783                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12784                 :                : 
 3440 sfrost@snowman.net      12785         [ +  + ]:CBC         158 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       12786                 :             38 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              12787                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      12788                 :             38 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       12789                 :             38 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              12790                 :                : 
                              12791                 :                :     /* Dump any per-constraint comments */
 3910 alvherre@alvh.no-ip.    12792         [ +  + ]:            271 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              12793                 :                :     {
                              12794                 :            113 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
                              12795                 :                :         PQExpBuffer conprefix;
                              12796                 :                : 
                              12797                 :                :         /* but only if the constraint itself was dumped here */
   52 alvherre@kurilemu.de    12798         [ +  + ]:            113 :         if (domcheck->separate)
                              12799                 :              5 :             continue;
                              12800                 :                : 
                              12801                 :            108 :         conprefix = createPQExpBuffer();
 2749 tgl@sss.pgh.pa.us       12802                 :            108 :         appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
 3910 alvherre@alvh.no-ip.    12803                 :            108 :                           fmtId(domcheck->dobj.name));
                              12804                 :                : 
 1039 tgl@sss.pgh.pa.us       12805         [ +  + ]:            108 :         if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749                         12806                 :             38 :             dumpComment(fout, conprefix->data, qtypname,
 3440 sfrost@snowman.net      12807                 :             38 :                         tyinfo->dobj.namespace->dobj.name,
                              12808                 :             38 :                         tyinfo->rolname,
                              12809                 :             38 :                         domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12810                 :                : 
 2749 tgl@sss.pgh.pa.us       12811                 :            108 :         destroyPQExpBuffer(conprefix);
                              12812                 :                :     }
                              12813                 :                : 
                              12814                 :                :     /*
                              12815                 :                :      * And a comment on the not-null constraint, if there's one -- but only if
                              12816                 :                :      * the constraint itself was dumped here
                              12817                 :                :      */
   47 alvherre@kurilemu.de    12818   [ +  +  +  - ]:            158 :     if (tyinfo->notnull != NULL && !tyinfo->notnull->separate)
                              12819                 :                :     {
                              12820                 :             53 :         PQExpBuffer conprefix = createPQExpBuffer();
                              12821                 :                : 
                              12822                 :             53 :         appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
                              12823                 :             53 :                           fmtId(tyinfo->notnull->dobj.name));
                              12824                 :                : 
                              12825         [ +  + ]:             53 :         if (tyinfo->notnull->dobj.dump & DUMP_COMPONENT_COMMENT)
                              12826                 :             38 :             dumpComment(fout, conprefix->data, qtypname,
                              12827                 :             38 :                         tyinfo->dobj.namespace->dobj.name,
                              12828                 :             38 :                         tyinfo->rolname,
                              12829                 :             38 :                         tyinfo->notnull->dobj.catId, 0, tyinfo->dobj.dumpId);
                              12830                 :             53 :         destroyPQExpBuffer(conprefix);
                              12831                 :                :     }
                              12832                 :                : 
 8520 tgl@sss.pgh.pa.us       12833                 :            158 :     destroyPQExpBuffer(q);
                              12834                 :            158 :     destroyPQExpBuffer(delq);
                              12835                 :            158 :     destroyPQExpBuffer(query);
 2749                         12836                 :            158 :     free(qtypname);
                              12837                 :            158 :     free(qualtypname);
 8555 bruce@momjian.us        12838                 :            158 : }
                              12839                 :                : 
                              12840                 :                : /*
                              12841                 :                :  * dumpCompositeType
                              12842                 :                :  *    writes out to fout the queries to recreate a user-defined stand-alone
                              12843                 :                :  *    composite type
                              12844                 :                :  */
                              12845                 :                : static void
 1669 peter@eisentraut.org    12846                 :            136 : dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
                              12847                 :                : {
 3524 tgl@sss.pgh.pa.us       12848                 :            136 :     DumpOptions *dopt = fout->dopt;
 8423 bruce@momjian.us        12849                 :            136 :     PQExpBuffer q = createPQExpBuffer();
 5222 heikki.linnakangas@i    12850                 :            136 :     PQExpBuffer dropped = createPQExpBuffer();
 8423 bruce@momjian.us        12851                 :            136 :     PQExpBuffer delq = createPQExpBuffer();
                              12852                 :            136 :     PQExpBuffer query = createPQExpBuffer();
                              12853                 :                :     PGresult   *res;
                              12854                 :                :     char       *qtypname;
                              12855                 :                :     char       *qualtypname;
                              12856                 :                :     int         ntups;
                              12857                 :                :     int         i_attname;
                              12858                 :                :     int         i_atttypdefn;
                              12859                 :                :     int         i_attlen;
                              12860                 :                :     int         i_attalign;
                              12861                 :                :     int         i_attisdropped;
                              12862                 :                :     int         i_attcollation;
                              12863                 :                :     int         i;
                              12864                 :                :     int         actual_atts;
                              12865                 :                : 
 1370 tgl@sss.pgh.pa.us       12866         [ +  + ]:            136 :     if (!fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE])
                              12867                 :                :     {
                              12868                 :                :         /*
                              12869                 :                :          * Set up query for type-specific details.
                              12870                 :                :          *
                              12871                 :                :          * Since we only want to dump COLLATE clauses for attributes whose
                              12872                 :                :          * collation is different from their type's default, we use a CASE
                              12873                 :                :          * here to suppress uninteresting attcollations cheaply.  atttypid
                              12874                 :                :          * will be 0 for dropped columns; collation does not matter for those.
                              12875                 :                :          */
                              12876                 :             61 :         appendPQExpBufferStr(query,
                              12877                 :                :                              "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
                              12878                 :                :                              "SELECT a.attname, a.attnum, "
                              12879                 :                :                              "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
                              12880                 :                :                              "a.attlen, a.attalign, a.attisdropped, "
                              12881                 :                :                              "CASE WHEN a.attcollation <> at.typcollation "
                              12882                 :                :                              "THEN a.attcollation ELSE 0 END AS attcollation "
                              12883                 :                :                              "FROM pg_catalog.pg_type ct "
                              12884                 :                :                              "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
                              12885                 :                :                              "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
                              12886                 :                :                              "WHERE ct.oid = $1 "
                              12887                 :                :                              "ORDER BY a.attnum");
                              12888                 :                : 
                              12889                 :             61 :         ExecuteSqlStatement(fout, query->data);
                              12890                 :                : 
                              12891                 :             61 :         fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE] = true;
                              12892                 :                :     }
                              12893                 :                : 
                              12894                 :            136 :     printfPQExpBuffer(query,
                              12895                 :                :                       "EXECUTE dumpCompositeType('%u')",
                              12896                 :            136 :                       tyinfo->dobj.catId.oid);
                              12897                 :                : 
 4960 rhaas@postgresql.org    12898                 :            136 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              12899                 :                : 
 8423 bruce@momjian.us        12900                 :            136 :     ntups = PQntuples(res);
                              12901                 :                : 
 8409 tgl@sss.pgh.pa.us       12902                 :            136 :     i_attname = PQfnumber(res, "attname");
                              12903                 :            136 :     i_atttypdefn = PQfnumber(res, "atttypdefn");
 5222 heikki.linnakangas@i    12904                 :            136 :     i_attlen = PQfnumber(res, "attlen");
                              12905                 :            136 :     i_attalign = PQfnumber(res, "attalign");
                              12906                 :            136 :     i_attisdropped = PQfnumber(res, "attisdropped");
 5256 tgl@sss.pgh.pa.us       12907                 :            136 :     i_attcollation = PQfnumber(res, "attcollation");
                              12908                 :                : 
 3980 alvherre@alvh.no-ip.    12909         [ +  + ]:            136 :     if (dopt->binary_upgrade)
                              12910                 :                :     {
 4960 rhaas@postgresql.org    12911                 :             18 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2898 tgl@sss.pgh.pa.us       12912                 :             18 :                                                  tyinfo->dobj.catId.oid,
                              12913                 :                :                                                  false, false);
  430 nathan@postgresql.or    12914                 :             18 :         binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid);
                              12915                 :                :     }
                              12916                 :                : 
 4654 tgl@sss.pgh.pa.us       12917                 :            136 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2749                         12918                 :            136 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              12919                 :                : 
 8409                         12920                 :            136 :     appendPQExpBuffer(q, "CREATE TYPE %s AS (",
                              12921                 :                :                       qualtypname);
                              12922                 :                : 
 5222 heikki.linnakangas@i    12923                 :            136 :     actual_atts = 0;
 8423 bruce@momjian.us        12924         [ +  + ]:            430 :     for (i = 0; i < ntups; i++)
                              12925                 :                :     {
                              12926                 :                :         char       *attname;
                              12927                 :                :         char       *atttypdefn;
                              12928                 :                :         char       *attlen;
                              12929                 :                :         char       *attalign;
                              12930                 :                :         bool        attisdropped;
                              12931                 :                :         Oid         attcollation;
                              12932                 :                : 
 8409 tgl@sss.pgh.pa.us       12933                 :            294 :         attname = PQgetvalue(res, i, i_attname);
                              12934                 :            294 :         atttypdefn = PQgetvalue(res, i, i_atttypdefn);
 5222 heikki.linnakangas@i    12935                 :            294 :         attlen = PQgetvalue(res, i, i_attlen);
                              12936                 :            294 :         attalign = PQgetvalue(res, i, i_attalign);
                              12937                 :            294 :         attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
 5256 tgl@sss.pgh.pa.us       12938                 :            294 :         attcollation = atooid(PQgetvalue(res, i, i_attcollation));
                              12939                 :                : 
 3980 alvherre@alvh.no-ip.    12940   [ +  +  +  + ]:            294 :         if (attisdropped && !dopt->binary_upgrade)
 5222 heikki.linnakangas@i    12941                 :              8 :             continue;
                              12942                 :                : 
                              12943                 :                :         /* Format properly if not first attr */
                              12944         [ +  + ]:            286 :         if (actual_atts++ > 0)
 4310                         12945                 :            150 :             appendPQExpBufferChar(q, ',');
                              12946                 :            286 :         appendPQExpBufferStr(q, "\n\t");
                              12947                 :                : 
 5222                         12948         [ +  + ]:            286 :         if (!attisdropped)
                              12949                 :                :         {
                              12950                 :            284 :             appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
                              12951                 :                : 
                              12952                 :                :             /* Add collation if not default for the column type */
                              12953         [ -  + ]:            284 :             if (OidIsValid(attcollation))
                              12954                 :                :             {
                              12955                 :                :                 CollInfo   *coll;
                              12956                 :                : 
 5222 heikki.linnakangas@i    12957                 :UBC           0 :                 coll = findCollationByOid(attcollation);
                              12958         [ #  # ]:              0 :                 if (coll)
 2749 tgl@sss.pgh.pa.us       12959                 :              0 :                     appendPQExpBuffer(q, " COLLATE %s",
                              12960                 :              0 :                                       fmtQualifiedDumpable(coll));
                              12961                 :                :             }
                              12962                 :                :         }
                              12963                 :                :         else
                              12964                 :                :         {
                              12965                 :                :             /*
                              12966                 :                :              * This is a dropped attribute and we're in binary_upgrade mode.
                              12967                 :                :              * Insert a placeholder for it in the CREATE TYPE command, and set
                              12968                 :                :              * length and alignment with direct UPDATE to the catalogs
                              12969                 :                :              * afterwards. See similar code in dumpTableSchema().
                              12970                 :                :              */
 5222 heikki.linnakangas@i    12971                 :CBC           2 :             appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
                              12972                 :                : 
                              12973                 :                :             /* stash separately for insertion after the CREATE TYPE */
 4310                         12974                 :              2 :             appendPQExpBufferStr(dropped,
                              12975                 :                :                                  "\n-- For binary upgrade, recreate dropped column.\n");
 5222                         12976                 :              2 :             appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
                              12977                 :                :                               "SET attlen = %s, "
                              12978                 :                :                               "attalign = '%s', attbyval = false\n"
                              12979                 :                :                               "WHERE attname = ", attlen, attalign);
                              12980                 :              2 :             appendStringLiteralAH(dropped, attname, fout);
 4310                         12981                 :              2 :             appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
 2749 tgl@sss.pgh.pa.us       12982                 :              2 :             appendStringLiteralAH(dropped, qualtypname, fout);
 4310 heikki.linnakangas@i    12983                 :              2 :             appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
                              12984                 :                : 
 5222                         12985                 :              2 :             appendPQExpBuffer(dropped, "ALTER TYPE %s ",
                              12986                 :                :                               qualtypname);
                              12987                 :              2 :             appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                              12988                 :                :                               fmtId(attname));
                              12989                 :                :         }
                              12990                 :                :     }
 4310                         12991                 :            136 :     appendPQExpBufferStr(q, "\n);\n");
 5222                         12992                 :            136 :     appendPQExpBufferStr(q, dropped->data);
                              12993                 :                : 
 2749 tgl@sss.pgh.pa.us       12994                 :            136 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              12995                 :                : 
 3980 alvherre@alvh.no-ip.    12996         [ +  + ]:            136 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       12997                 :             18 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              12998                 :                :                                         "TYPE", qtypname,
                              12999                 :             18 :                                         tyinfo->dobj.namespace->dobj.name);
                              13000                 :                : 
 3440 sfrost@snowman.net      13001         [ +  + ]:            136 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13002                 :            119 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13003                 :            119 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              13004                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              13005                 :                :                                   .owner = tyinfo->rolname,
                              13006                 :                :                                   .description = "TYPE",
                              13007                 :                :                                   .section = SECTION_PRE_DATA,
                              13008                 :                :                                   .createStmt = q->data,
                              13009                 :                :                                   .dropStmt = delq->data));
                              13010                 :                : 
                              13011                 :                : 
                              13012                 :                :     /* Dump Type Comments and Security Labels */
 3440 sfrost@snowman.net      13013         [ +  + ]:            136 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       13014                 :             38 :         dumpComment(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      13015                 :             38 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              13016                 :             38 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              13017                 :                : 
                              13018         [ -  + ]:            136 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       13019                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 3440 sfrost@snowman.net      13020                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              13021                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              13022                 :                : 
 3440 sfrost@snowman.net      13023         [ +  + ]:CBC         136 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       13024                 :             18 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              13025                 :                :                 qtypname, NULL,
 3440 sfrost@snowman.net      13026                 :             18 :                 tyinfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       13027                 :             18 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              13028                 :                : 
                              13029                 :                :     /* Dump any per-column comments */
 1346                         13030         [ +  + ]:            136 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              13031                 :             38 :         dumpCompositeTypeColComments(fout, tyinfo, res);
                              13032                 :                : 
 7945                         13033                 :            136 :     PQclear(res);
                              13034                 :            136 :     destroyPQExpBuffer(q);
 5222 heikki.linnakangas@i    13035                 :            136 :     destroyPQExpBuffer(dropped);
 7945 tgl@sss.pgh.pa.us       13036                 :            136 :     destroyPQExpBuffer(delq);
                              13037                 :            136 :     destroyPQExpBuffer(query);
 2749                         13038                 :            136 :     free(qtypname);
                              13039                 :            136 :     free(qualtypname);
 5889                         13040                 :            136 : }
                              13041                 :                : 
                              13042                 :                : /*
                              13043                 :                :  * dumpCompositeTypeColComments
                              13044                 :                :  *    writes out to fout the queries to recreate comments on the columns of
                              13045                 :                :  *    a user-defined stand-alone composite type.
                              13046                 :                :  *
                              13047                 :                :  * The caller has already made a query to collect the names and attnums
                              13048                 :                :  * of the type's columns, so we just pass that result into here rather
                              13049                 :                :  * than reading them again.
                              13050                 :                :  */
                              13051                 :                : static void
 1346                         13052                 :             38 : dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
                              13053                 :                :                              PGresult *res)
                              13054                 :                : {
                              13055                 :                :     CommentItem *comments;
                              13056                 :                :     int         ncomments;
                              13057                 :                :     PQExpBuffer query;
                              13058                 :                :     PQExpBuffer target;
                              13059                 :                :     int         i;
                              13060                 :                :     int         ntups;
                              13061                 :                :     int         i_attname;
                              13062                 :                :     int         i_attnum;
                              13063                 :                :     int         i_attisdropped;
                              13064                 :                : 
                              13065                 :                :     /* do nothing, if --no-comments is supplied */
 2781                         13066         [ -  + ]:             38 :     if (fout->dopt->no_comments)
 2781 tgl@sss.pgh.pa.us       13067                 :UBC           0 :         return;
                              13068                 :                : 
                              13069                 :                :     /* Search for comments associated with type's pg_class OID */
 1346 tgl@sss.pgh.pa.us       13070                 :CBC          38 :     ncomments = findComments(RelationRelationId, tyinfo->typrelid,
                              13071                 :                :                              &comments);
                              13072                 :                : 
                              13073                 :                :     /* If no comments exist, we're done */
 5889                         13074         [ -  + ]:             38 :     if (ncomments <= 0)
 5889 tgl@sss.pgh.pa.us       13075                 :UBC           0 :         return;
                              13076                 :                : 
                              13077                 :                :     /* Build COMMENT ON statements */
 1346 tgl@sss.pgh.pa.us       13078                 :CBC          38 :     query = createPQExpBuffer();
 5889                         13079                 :             38 :     target = createPQExpBuffer();
                              13080                 :                : 
 1346                         13081                 :             38 :     ntups = PQntuples(res);
 5889                         13082                 :             38 :     i_attnum = PQfnumber(res, "attnum");
                              13083                 :             38 :     i_attname = PQfnumber(res, "attname");
 1346                         13084                 :             38 :     i_attisdropped = PQfnumber(res, "attisdropped");
 5889                         13085         [ +  + ]:             76 :     while (ncomments > 0)
                              13086                 :                :     {
                              13087                 :                :         const char *attname;
                              13088                 :                : 
                              13089                 :             38 :         attname = NULL;
                              13090         [ +  - ]:             38 :         for (i = 0; i < ntups; i++)
                              13091                 :                :         {
 1346                         13092         [ +  - ]:             38 :             if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
                              13093         [ +  - ]:             38 :                 PQgetvalue(res, i, i_attisdropped)[0] != 't')
                              13094                 :                :             {
 5889                         13095                 :             38 :                 attname = PQgetvalue(res, i, i_attname);
                              13096                 :             38 :                 break;
                              13097                 :                :             }
                              13098                 :                :         }
                              13099         [ +  - ]:             38 :         if (attname)            /* just in case we don't find it */
                              13100                 :                :         {
                              13101                 :             38 :             const char *descr = comments->descr;
                              13102                 :                : 
                              13103                 :             38 :             resetPQExpBuffer(target);
                              13104                 :             38 :             appendPQExpBuffer(target, "COLUMN %s.",
 5736 bruce@momjian.us        13105                 :             38 :                               fmtId(tyinfo->dobj.name));
 4310 heikki.linnakangas@i    13106                 :             38 :             appendPQExpBufferStr(target, fmtId(attname));
                              13107                 :                : 
 5889 tgl@sss.pgh.pa.us       13108                 :             38 :             resetPQExpBuffer(query);
 2749                         13109                 :             38 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              13110                 :             38 :                               fmtQualifiedDumpable(tyinfo));
                              13111                 :             38 :             appendPQExpBuffer(query, "%s IS ", fmtId(attname));
 5889                         13112                 :             38 :             appendStringLiteralAH(query, descr, fout);
 4310 heikki.linnakangas@i    13113                 :             38 :             appendPQExpBufferStr(query, ";\n");
                              13114                 :                : 
 5889 tgl@sss.pgh.pa.us       13115                 :             38 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    13116                 :             38 :                          ARCHIVE_OPTS(.tag = target->data,
                              13117                 :                :                                       .namespace = tyinfo->dobj.namespace->dobj.name,
                              13118                 :                :                                       .owner = tyinfo->rolname,
                              13119                 :                :                                       .description = "COMMENT",
                              13120                 :                :                                       .section = SECTION_NONE,
                              13121                 :                :                                       .createStmt = query->data,
                              13122                 :                :                                       .deps = &(tyinfo->dobj.dumpId),
                              13123                 :                :                                       .nDeps = 1));
                              13124                 :                :         }
                              13125                 :                : 
 5889 tgl@sss.pgh.pa.us       13126                 :             38 :         comments++;
                              13127                 :             38 :         ncomments--;
                              13128                 :                :     }
                              13129                 :                : 
                              13130                 :             38 :     destroyPQExpBuffer(query);
                              13131                 :             38 :     destroyPQExpBuffer(target);
                              13132                 :                : }
                              13133                 :                : 
                              13134                 :                : /*
                              13135                 :                :  * dumpShellType
                              13136                 :                :  *    writes out to fout the queries to create a shell type
                              13137                 :                :  *
                              13138                 :                :  * We dump a shell definition in advance of the I/O functions for the type.
                              13139                 :                :  */
                              13140                 :                : static void
 1669 peter@eisentraut.org    13141                 :             79 : dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
                              13142                 :                : {
 3524 tgl@sss.pgh.pa.us       13143                 :             79 :     DumpOptions *dopt = fout->dopt;
                              13144                 :                :     PQExpBuffer q;
                              13145                 :                : 
                              13146                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    13147         [ +  + ]:             79 :     if (!dopt->dumpSchema)
 7128 tgl@sss.pgh.pa.us       13148                 :              6 :         return;
                              13149                 :                : 
                              13150                 :             73 :     q = createPQExpBuffer();
                              13151                 :                : 
                              13152                 :                :     /*
                              13153                 :                :      * Note the lack of a DROP command for the shell type; any required DROP
                              13154                 :                :      * is driven off the base type entry, instead.  This interacts with
                              13155                 :                :      * _printTocEntry()'s use of the presence of a DROP command to decide
                              13156                 :                :      * whether an entry needs an ALTER OWNER command.  We don't want to alter
                              13157                 :                :      * the shell type's owner immediately on creation; that should happen only
                              13158                 :                :      * after it's filled in, otherwise the backend complains.
                              13159                 :                :      */
                              13160                 :                : 
 3980 alvherre@alvh.no-ip.    13161         [ +  + ]:             73 :     if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    13162                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2898 tgl@sss.pgh.pa.us       13163                 :              8 :                                                  stinfo->baseType->dobj.catId.oid,
                              13164                 :                :                                                  false, false);
                              13165                 :                : 
 7128                         13166                 :             73 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
 2749                         13167                 :             73 :                       fmtQualifiedDumpable(stinfo));
                              13168                 :                : 
 3440 sfrost@snowman.net      13169         [ +  - ]:             73 :     if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13170                 :             73 :         ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13171                 :             73 :                      ARCHIVE_OPTS(.tag = stinfo->dobj.name,
                              13172                 :                :                                   .namespace = stinfo->dobj.namespace->dobj.name,
                              13173                 :                :                                   .owner = stinfo->baseType->rolname,
                              13174                 :                :                                   .description = "SHELL TYPE",
                              13175                 :                :                                   .section = SECTION_PRE_DATA,
                              13176                 :                :                                   .createStmt = q->data));
                              13177                 :                : 
 7128 tgl@sss.pgh.pa.us       13178                 :             73 :     destroyPQExpBuffer(q);
                              13179                 :                : }
                              13180                 :                : 
                              13181                 :                : /*
                              13182                 :                :  * dumpProcLang
                              13183                 :                :  *        writes out to fout the queries to recreate a user-defined
                              13184                 :                :  *        procedural language
                              13185                 :                :  */
                              13186                 :                : static void
 1669 peter@eisentraut.org    13187                 :             94 : dumpProcLang(Archive *fout, const ProcLangInfo *plang)
                              13188                 :                : {
 3524 tgl@sss.pgh.pa.us       13189                 :             94 :     DumpOptions *dopt = fout->dopt;
                              13190                 :                :     PQExpBuffer defqry;
                              13191                 :                :     PQExpBuffer delqry;
                              13192                 :                :     bool        useParams;
                              13193                 :                :     char       *qlanname;
                              13194                 :                :     FuncInfo   *funcInfo;
 5828                         13195                 :             94 :     FuncInfo   *inlineInfo = NULL;
 7945                         13196                 :             94 :     FuncInfo   *validatorInfo = NULL;
                              13197                 :                : 
                              13198                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    13199         [ +  + ]:             94 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       13200                 :             13 :         return;
                              13201                 :                : 
                              13202                 :                :     /*
                              13203                 :                :      * Try to find the support function(s).  It is not an error if we don't
                              13204                 :                :      * find them --- if the functions are in the pg_catalog schema, as is
                              13205                 :                :      * standard in 8.1 and up, then we won't have loaded them. (In this case
                              13206                 :                :      * we will emit a parameterless CREATE LANGUAGE command, which will
                              13207                 :                :      * require PL template knowledge in the backend to reload.)
                              13208                 :                :      */
                              13209                 :                : 
                              13210                 :             81 :     funcInfo = findFuncByOid(plang->lanplcallfoid);
 7128                         13211   [ +  +  +  + ]:             81 :     if (funcInfo != NULL && !funcInfo->dobj.dump)
 7306                         13212                 :              2 :         funcInfo = NULL;        /* treat not-dumped same as not-found */
                              13213                 :                : 
 5828                         13214         [ +  + ]:             81 :     if (OidIsValid(plang->laninline))
                              13215                 :                :     {
                              13216                 :             44 :         inlineInfo = findFuncByOid(plang->laninline);
                              13217   [ +  +  +  - ]:             44 :         if (inlineInfo != NULL && !inlineInfo->dobj.dump)
                              13218                 :              1 :             inlineInfo = NULL;
                              13219                 :                :     }
                              13220                 :                : 
 7945                         13221         [ +  + ]:             81 :     if (OidIsValid(plang->lanvalidator))
                              13222                 :                :     {
                              13223                 :             44 :         validatorInfo = findFuncByOid(plang->lanvalidator);
 7128                         13224   [ +  +  +  - ]:             44 :         if (validatorInfo != NULL && !validatorInfo->dobj.dump)
 7306                         13225                 :              1 :             validatorInfo = NULL;
                              13226                 :                :     }
                              13227                 :                : 
                              13228                 :                :     /*
                              13229                 :                :      * If the functions are dumpable then emit a complete CREATE LANGUAGE with
                              13230                 :                :      * parameters.  Otherwise, we'll write a parameterless command, which will
                              13231                 :                :      * be interpreted as CREATE EXTENSION.
                              13232                 :                :      */
                              13233         [ +  - ]:             36 :     useParams = (funcInfo != NULL &&
 5828                         13234   [ +  +  +  -  :            153 :                  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
                                              +  - ]
 7306                         13235         [ +  - ]:             36 :                  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
                              13236                 :                : 
 7945                         13237                 :             81 :     defqry = createPQExpBuffer();
                              13238                 :             81 :     delqry = createPQExpBuffer();
                              13239                 :                : 
 5034 bruce@momjian.us        13240                 :             81 :     qlanname = pg_strdup(fmtId(plang->dobj.name));
                              13241                 :                : 
 7945 tgl@sss.pgh.pa.us       13242                 :             81 :     appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                              13243                 :                :                       qlanname);
                              13244                 :                : 
 7306                         13245         [ +  + ]:             81 :     if (useParams)
                              13246                 :                :     {
 5673                         13247                 :             36 :         appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
                              13248         [ -  + ]:             36 :                           plang->lanpltrusted ? "TRUSTED " : "",
                              13249                 :                :                           qlanname);
 7306                         13250                 :             36 :         appendPQExpBuffer(defqry, " HANDLER %s",
 2749                         13251                 :             36 :                           fmtQualifiedDumpable(funcInfo));
 5828                         13252         [ -  + ]:             36 :         if (OidIsValid(plang->laninline))
 2749 tgl@sss.pgh.pa.us       13253                 :UBC           0 :             appendPQExpBuffer(defqry, " INLINE %s",
                              13254                 :              0 :                               fmtQualifiedDumpable(inlineInfo));
 7306 tgl@sss.pgh.pa.us       13255         [ -  + ]:CBC          36 :         if (OidIsValid(plang->lanvalidator))
 2749 tgl@sss.pgh.pa.us       13256                 :UBC           0 :             appendPQExpBuffer(defqry, " VALIDATOR %s",
                              13257                 :              0 :                               fmtQualifiedDumpable(validatorInfo));
                              13258                 :                :     }
                              13259                 :                :     else
                              13260                 :                :     {
                              13261                 :                :         /*
                              13262                 :                :          * If not dumping parameters, then use CREATE OR REPLACE so that the
                              13263                 :                :          * command will not fail if the language is preinstalled in the target
                              13264                 :                :          * database.
                              13265                 :                :          *
                              13266                 :                :          * Modern servers will interpret this as CREATE EXTENSION IF NOT
                              13267                 :                :          * EXISTS; perhaps we should emit that instead?  But it might just add
                              13268                 :                :          * confusion.
                              13269                 :                :          */
 5673 tgl@sss.pgh.pa.us       13270                 :CBC          45 :         appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
                              13271                 :                :                           qlanname);
                              13272                 :                :     }
 4310 heikki.linnakangas@i    13273                 :             81 :     appendPQExpBufferStr(defqry, ";\n");
                              13274                 :                : 
 3980 alvherre@alvh.no-ip.    13275         [ +  + ]:             81 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       13276                 :              2 :         binary_upgrade_extension_member(defqry, &plang->dobj,
                              13277                 :                :                                         "LANGUAGE", qlanname, NULL);
                              13278                 :                : 
 3440 sfrost@snowman.net      13279         [ +  + ]:             81 :     if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13280                 :             37 :         ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13281                 :             37 :                      ARCHIVE_OPTS(.tag = plang->dobj.name,
                              13282                 :                :                                   .owner = plang->lanowner,
                              13283                 :                :                                   .description = "PROCEDURAL LANGUAGE",
                              13284                 :                :                                   .section = SECTION_PRE_DATA,
                              13285                 :                :                                   .createStmt = defqry->data,
                              13286                 :                :                                   .dropStmt = delqry->data,
                              13287                 :                :                                   ));
                              13288                 :                : 
                              13289                 :                :     /* Dump Proc Lang Comments and Security Labels */
 3440 sfrost@snowman.net      13290         [ -  + ]:             81 :     if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       13291                 :UBC           0 :         dumpComment(fout, "LANGUAGE", qlanname,
                              13292                 :              0 :                     NULL, plang->lanowner,
 3440 sfrost@snowman.net      13293                 :              0 :                     plang->dobj.catId, 0, plang->dobj.dumpId);
                              13294                 :                : 
 3440 sfrost@snowman.net      13295         [ -  + ]:CBC          81 :     if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       13296                 :UBC           0 :         dumpSecLabel(fout, "LANGUAGE", qlanname,
                              13297                 :              0 :                      NULL, plang->lanowner,
 3440 sfrost@snowman.net      13298                 :              0 :                      plang->dobj.catId, 0, plang->dobj.dumpId);
                              13299                 :                : 
 3440 sfrost@snowman.net      13300   [ +  +  +  - ]:CBC          81 :     if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       13301                 :             44 :         dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
                              13302                 :                :                 qlanname, NULL, NULL,
  523                         13303                 :             44 :                 NULL, plang->lanowner, &plang->dacl);
                              13304                 :                : 
 7945                         13305                 :             81 :     free(qlanname);
                              13306                 :                : 
                              13307                 :             81 :     destroyPQExpBuffer(defqry);
                              13308                 :             81 :     destroyPQExpBuffer(delqry);
                              13309                 :                : }
                              13310                 :                : 
                              13311                 :                : /*
                              13312                 :                :  * format_function_arguments: generate function name and argument list
                              13313                 :                :  *
                              13314                 :                :  * This is used when we can rely on pg_get_function_arguments to format
                              13315                 :                :  * the argument list.  Note, however, that pg_get_function_arguments
                              13316                 :                :  * does not special-case zero-argument aggregates.
                              13317                 :                :  */
                              13318                 :                : static char *
 1669 peter@eisentraut.org    13319                 :           4204 : format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
                              13320                 :                : {
                              13321                 :                :     PQExpBufferData fn;
                              13322                 :                : 
 6259 tgl@sss.pgh.pa.us       13323                 :           4204 :     initPQExpBuffer(&fn);
 4310 heikki.linnakangas@i    13324                 :           4204 :     appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
 4386 tgl@sss.pgh.pa.us       13325   [ +  +  +  + ]:           4204 :     if (is_agg && finfo->nargs == 0)
 4310 heikki.linnakangas@i    13326                 :             80 :         appendPQExpBufferStr(&fn, "(*)");
                              13327                 :                :     else
 4386 tgl@sss.pgh.pa.us       13328                 :           4124 :         appendPQExpBuffer(&fn, "(%s)", funcargs);
 6259                         13329                 :           4204 :     return fn.data;
                              13330                 :                : }
                              13331                 :                : 
                              13332                 :                : /*
                              13333                 :                :  * format_function_signature: generate function name and argument list
                              13334                 :                :  *
                              13335                 :                :  * Only a minimal list of input argument types is generated; this is
                              13336                 :                :  * sufficient to reference the function, but not to define it.
                              13337                 :                :  *
                              13338                 :                :  * If honor_quotes is false then the function name is never quoted.
                              13339                 :                :  * This is appropriate for use in TOC tags, but not in SQL commands.
                              13340                 :                :  */
                              13341                 :                : static char *
 1669 peter@eisentraut.org    13342                 :           2228 : format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
                              13343                 :                : {
                              13344                 :                :     PQExpBufferData fn;
                              13345                 :                :     int         j;
                              13346                 :                : 
 7463 tgl@sss.pgh.pa.us       13347                 :           2228 :     initPQExpBuffer(&fn);
                              13348         [ +  + ]:           2228 :     if (honor_quotes)
                              13349                 :            417 :         appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
                              13350                 :                :     else
                              13351                 :           1811 :         appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
                              13352         [ +  + ]:           4072 :     for (j = 0; j < finfo->nargs; j++)
                              13353                 :                :     {
 4310 heikki.linnakangas@i    13354         [ +  + ]:           1844 :         if (j > 0)
                              13355                 :            422 :             appendPQExpBufferStr(&fn, ", ");
                              13356                 :                : 
 1459 tgl@sss.pgh.pa.us       13357                 :           1844 :         appendPQExpBufferStr(&fn,
                              13358                 :           1844 :                              getFormattedTypeName(fout, finfo->argtypes[j],
                              13359                 :                :                                                   zeroIsError));
                              13360                 :                :     }
 4310 heikki.linnakangas@i    13361                 :           2228 :     appendPQExpBufferChar(&fn, ')');
 7463 tgl@sss.pgh.pa.us       13362                 :           2228 :     return fn.data;
                              13363                 :                : }
                              13364                 :                : 
                              13365                 :                : 
                              13366                 :                : /*
                              13367                 :                :  * dumpFunc:
                              13368                 :                :  *    dump out one function
                              13369                 :                :  */
                              13370                 :                : static void
 1669 peter@eisentraut.org    13371                 :           1873 : dumpFunc(Archive *fout, const FuncInfo *finfo)
                              13372                 :                : {
 3524 tgl@sss.pgh.pa.us       13373                 :           1873 :     DumpOptions *dopt = fout->dopt;
                              13374                 :                :     PQExpBuffer query;
                              13375                 :                :     PQExpBuffer q;
                              13376                 :                :     PQExpBuffer delqry;
                              13377                 :                :     PQExpBuffer asPart;
                              13378                 :                :     PGresult   *res;
                              13379                 :                :     char       *funcsig;        /* identity signature */
 2999                         13380                 :           1873 :     char       *funcfullsig = NULL; /* full signature */
                              13381                 :                :     char       *funcsig_tag;
                              13382                 :                :     char       *qual_funcsig;
                              13383                 :                :     char       *proretset;
                              13384                 :                :     char       *prosrc;
                              13385                 :                :     char       *probin;
                              13386                 :                :     char       *prosqlbody;
                              13387                 :                :     char       *funcargs;
                              13388                 :                :     char       *funciargs;
                              13389                 :                :     char       *funcresult;
                              13390                 :                :     char       *protrftypes;
                              13391                 :                :     char       *prokind;
                              13392                 :                :     char       *provolatile;
                              13393                 :                :     char       *proisstrict;
                              13394                 :                :     char       *prosecdef;
                              13395                 :                :     char       *proleakproof;
                              13396                 :                :     char       *proconfig;
                              13397                 :                :     char       *procost;
                              13398                 :                :     char       *prorows;
                              13399                 :                :     char       *prosupport;
                              13400                 :                :     char       *proparallel;
                              13401                 :                :     char       *lanname;
 6578                         13402                 :           1873 :     char      **configitems = NULL;
                              13403                 :           1873 :     int         nconfigitems = 0;
                              13404                 :                :     const char *keyword;
                              13405                 :                : 
                              13406                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    13407         [ +  + ]:           1873 :     if (!dopt->dumpSchema)
 7327 tgl@sss.pgh.pa.us       13408                 :             62 :         return;
                              13409                 :                : 
 7945                         13410                 :           1811 :     query = createPQExpBuffer();
                              13411                 :           1811 :     q = createPQExpBuffer();
                              13412                 :           1811 :     delqry = createPQExpBuffer();
                              13413                 :           1811 :     asPart = createPQExpBuffer();
                              13414                 :                : 
 1370                         13415         [ +  + ]:           1811 :     if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
                              13416                 :                :     {
                              13417                 :                :         /* Set up query for function-specific details */
 1787 drowley@postgresql.o    13418                 :             67 :         appendPQExpBufferStr(query,
                              13419                 :                :                              "PREPARE dumpFunc(pg_catalog.oid) AS\n");
                              13420                 :                : 
                              13421                 :             67 :         appendPQExpBufferStr(query,
                              13422                 :                :                              "SELECT\n"
                              13423                 :                :                              "proretset,\n"
                              13424                 :                :                              "prosrc,\n"
                              13425                 :                :                              "probin,\n"
                              13426                 :                :                              "provolatile,\n"
                              13427                 :                :                              "proisstrict,\n"
                              13428                 :                :                              "prosecdef,\n"
                              13429                 :                :                              "lanname,\n"
                              13430                 :                :                              "proconfig,\n"
                              13431                 :                :                              "procost,\n"
                              13432                 :                :                              "prorows,\n"
                              13433                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              13434                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
                              13435                 :                :                              "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
                              13436                 :                :                              "proleakproof,\n");
                              13437                 :                : 
 1370 tgl@sss.pgh.pa.us       13438         [ +  - ]:             67 :         if (fout->remoteVersion >= 90500)
                              13439                 :             67 :             appendPQExpBufferStr(query,
                              13440                 :                :                                  "array_to_string(protrftypes, ' ') AS protrftypes,\n");
                              13441                 :                :         else
 1357 tgl@sss.pgh.pa.us       13442                 :UBC           0 :             appendPQExpBufferStr(query,
                              13443                 :                :                                  "NULL AS protrftypes,\n");
                              13444                 :                : 
 1370 tgl@sss.pgh.pa.us       13445         [ +  - ]:CBC          67 :         if (fout->remoteVersion >= 90600)
                              13446                 :             67 :             appendPQExpBufferStr(query,
                              13447                 :                :                                  "proparallel,\n");
                              13448                 :                :         else
 1370 tgl@sss.pgh.pa.us       13449                 :UBC           0 :             appendPQExpBufferStr(query,
                              13450                 :                :                                  "'u' AS proparallel,\n");
                              13451                 :                : 
 1370 tgl@sss.pgh.pa.us       13452         [ +  - ]:CBC          67 :         if (fout->remoteVersion >= 110000)
                              13453                 :             67 :             appendPQExpBufferStr(query,
                              13454                 :                :                                  "prokind,\n");
                              13455                 :                :         else
 1370 tgl@sss.pgh.pa.us       13456                 :UBC           0 :             appendPQExpBufferStr(query,
                              13457                 :                :                                  "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
                              13458                 :                : 
 1370 tgl@sss.pgh.pa.us       13459         [ +  - ]:CBC          67 :         if (fout->remoteVersion >= 120000)
                              13460                 :             67 :             appendPQExpBufferStr(query,
                              13461                 :                :                                  "prosupport,\n");
                              13462                 :                :         else
 1370 tgl@sss.pgh.pa.us       13463                 :UBC           0 :             appendPQExpBufferStr(query,
                              13464                 :                :                                  "'-' AS prosupport,\n");
                              13465                 :                : 
 1370 tgl@sss.pgh.pa.us       13466         [ +  - ]:CBC          67 :         if (fout->remoteVersion >= 140000)
                              13467                 :             67 :             appendPQExpBufferStr(query,
                              13468                 :                :                                  "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
                              13469                 :                :         else
 1370 tgl@sss.pgh.pa.us       13470                 :UBC           0 :             appendPQExpBufferStr(query,
                              13471                 :                :                                  "NULL AS prosqlbody\n");
                              13472                 :                : 
 1613 peter@eisentraut.org    13473                 :CBC          67 :         appendPQExpBufferStr(query,
                              13474                 :                :                              "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
                              13475                 :                :                              "WHERE p.oid = $1 "
                              13476                 :                :                              "AND l.oid = p.prolang");
                              13477                 :                : 
 1370 tgl@sss.pgh.pa.us       13478                 :             67 :         ExecuteSqlStatement(fout, query->data);
                              13479                 :                : 
                              13480                 :             67 :         fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
                              13481                 :                :     }
                              13482                 :                : 
                              13483                 :           1811 :     printfPQExpBuffer(query,
                              13484                 :                :                       "EXECUTE dumpFunc('%u')",
 1879 peter@eisentraut.org    13485                 :           1811 :                       finfo->dobj.catId.oid);
                              13486                 :                : 
 4951 rhaas@postgresql.org    13487                 :           1811 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13488                 :                : 
 8520 tgl@sss.pgh.pa.us       13489                 :           1811 :     proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
 1613 peter@eisentraut.org    13490         [ +  + ]:           1811 :     if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
                              13491                 :                :     {
                              13492                 :           1757 :         prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
                              13493                 :           1757 :         probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
                              13494                 :           1757 :         prosqlbody = NULL;
                              13495                 :                :     }
                              13496                 :                :     else
                              13497                 :                :     {
                              13498                 :             54 :         prosrc = NULL;
                              13499                 :             54 :         probin = NULL;
                              13500                 :             54 :         prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
                              13501                 :                :     }
 1362 tgl@sss.pgh.pa.us       13502                 :           1811 :     funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              13503                 :           1811 :     funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              13504                 :           1811 :     funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
 1357                         13505                 :           1811 :     protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
 2745 peter_e@gmx.net         13506                 :           1811 :     prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
 8520 tgl@sss.pgh.pa.us       13507                 :           1811 :     provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
                              13508                 :           1811 :     proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
 8512 peter_e@gmx.net         13509                 :           1811 :     prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
 4954 rhaas@postgresql.org    13510                 :           1811 :     proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
 6578 tgl@sss.pgh.pa.us       13511                 :           1811 :     proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
 6802                         13512                 :           1811 :     procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
                              13513                 :           1811 :     prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
 2401                         13514                 :           1811 :     prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
 1879 peter@eisentraut.org    13515                 :           1811 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
 8520 tgl@sss.pgh.pa.us       13516                 :           1811 :     lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
                              13517                 :                : 
                              13518                 :                :     /*
                              13519                 :                :      * See backend/commands/functioncmds.c for details of how the 'AS' clause
                              13520                 :                :      * is used.
                              13521                 :                :      */
 1613 peter@eisentraut.org    13522         [ +  + ]:           1811 :     if (prosqlbody)
                              13523                 :                :     {
                              13524                 :             54 :         appendPQExpBufferStr(asPart, prosqlbody);
                              13525                 :                :     }
 1360 tgl@sss.pgh.pa.us       13526         [ +  + ]:           1757 :     else if (probin[0] != '\0')
                              13527                 :                :     {
 4310 heikki.linnakangas@i    13528                 :            138 :         appendPQExpBufferStr(asPart, "AS ");
 7041 tgl@sss.pgh.pa.us       13529                 :            138 :         appendStringLiteralAH(asPart, probin, fout);
 1360                         13530         [ +  - ]:            138 :         if (prosrc[0] != '\0')
                              13531                 :                :         {
 4310 heikki.linnakangas@i    13532                 :            138 :             appendPQExpBufferStr(asPart, ", ");
                              13533                 :                : 
                              13534                 :                :             /*
                              13535                 :                :              * where we have bin, use dollar quoting if allowed and src
                              13536                 :                :              * contains quote or backslash; else use regular quoting.
                              13537                 :                :              */
 3980 alvherre@alvh.no-ip.    13538         [ +  - ]:            138 :             if (dopt->disable_dollar_quoting ||
 2999 tgl@sss.pgh.pa.us       13539   [ +  -  +  - ]:            138 :                 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
 7041                         13540                 :            138 :                 appendStringLiteralAH(asPart, prosrc, fout);
                              13541                 :                :             else
 7041 tgl@sss.pgh.pa.us       13542                 :UBC           0 :                 appendStringLiteralDQ(asPart, prosrc, NULL);
                              13543                 :                :         }
                              13544                 :                :     }
                              13545                 :                :     else
                              13546                 :                :     {
 1360 tgl@sss.pgh.pa.us       13547                 :CBC        1619 :         appendPQExpBufferStr(asPart, "AS ");
                              13548                 :                :         /* with no bin, dollar quote src unconditionally if allowed */
                              13549         [ -  + ]:           1619 :         if (dopt->disable_dollar_quoting)
 1360 tgl@sss.pgh.pa.us       13550                 :UBC           0 :             appendStringLiteralAH(asPart, prosrc, fout);
                              13551                 :                :         else
 1360 tgl@sss.pgh.pa.us       13552                 :CBC        1619 :             appendStringLiteralDQ(asPart, prosrc, NULL);
                              13553                 :                :     }
                              13554                 :                : 
 1357                         13555         [ +  + ]:           1811 :     if (*proconfig)
                              13556                 :                :     {
 6578                         13557         [ -  + ]:             15 :         if (!parsePGArray(proconfig, &configitems, &nconfigitems))
 1247 tgl@sss.pgh.pa.us       13558                 :UBC           0 :             pg_fatal("could not parse %s array", "proconfig");
                              13559                 :                :     }
                              13560                 :                :     else
                              13561                 :                :     {
 1752 michael@paquier.xyz     13562                 :CBC        1796 :         configitems = NULL;
                              13563                 :           1796 :         nconfigitems = 0;
                              13564                 :                :     }
                              13565                 :                : 
 1362 tgl@sss.pgh.pa.us       13566                 :           1811 :     funcfullsig = format_function_arguments(finfo, funcargs, false);
                              13567                 :           1811 :     funcsig = format_function_arguments(finfo, funciargs, false);
                              13568                 :                : 
 4961 rhaas@postgresql.org    13569                 :           1811 :     funcsig_tag = format_function_signature(fout, finfo, false);
                              13570                 :                : 
 1413 tgl@sss.pgh.pa.us       13571                 :           1811 :     qual_funcsig = psprintf("%s.%s",
                              13572                 :           1811 :                             fmtId(finfo->dobj.namespace->dobj.name),
                              13573                 :                :                             funcsig);
                              13574                 :                : 
 2745 peter_e@gmx.net         13575         [ +  + ]:           1811 :     if (prokind[0] == PROKIND_PROCEDURE)
                              13576                 :             98 :         keyword = "PROCEDURE";
                              13577                 :                :     else
                              13578                 :           1713 :         keyword = "FUNCTION"; /* works for window functions too */
                              13579                 :                : 
 1413 tgl@sss.pgh.pa.us       13580                 :           1811 :     appendPQExpBuffer(delqry, "DROP %s %s;\n",
                              13581                 :                :                       keyword, qual_funcsig);
                              13582                 :                : 
 2749                         13583         [ +  - ]:           3622 :     appendPQExpBuffer(q, "CREATE %s %s.%s",
                              13584                 :                :                       keyword,
                              13585                 :           1811 :                       fmtId(finfo->dobj.namespace->dobj.name),
                              13586                 :                :                       funcfullsig ? funcfullsig :
                              13587                 :                :                       funcsig);
                              13588                 :                : 
 2745 peter_e@gmx.net         13589         [ +  + ]:           1811 :     if (prokind[0] == PROKIND_PROCEDURE)
                              13590                 :                :          /* no result type to output */ ;
 2837                         13591         [ +  - ]:           1713 :     else if (funcresult)
                              13592                 :           1713 :         appendPQExpBuffer(q, " RETURNS %s", funcresult);
                              13593                 :                :     else
 2837 peter_e@gmx.net         13594                 :UBC           0 :         appendPQExpBuffer(q, " RETURNS %s%s",
 6259 tgl@sss.pgh.pa.us       13595         [ #  # ]:              0 :                           (proretset[0] == 't') ? "SETOF " : "",
 1459                         13596                 :              0 :                           getFormattedTypeName(fout, finfo->prorettype,
                              13597                 :                :                                                zeroIsError));
                              13598                 :                : 
 6276 heikki.linnakangas@i    13599                 :CBC        1811 :     appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));
                              13600                 :                : 
 1357 tgl@sss.pgh.pa.us       13601         [ -  + ]:           1811 :     if (*protrftypes)
                              13602                 :                :     {
  269 dgustafsson@postgres    13603                 :UBC           0 :         Oid        *typeids = pg_malloc(FUNC_MAX_ARGS * sizeof(Oid));
                              13604                 :                :         int         i;
                              13605                 :                : 
 3786 peter_e@gmx.net         13606                 :              0 :         appendPQExpBufferStr(q, " TRANSFORM ");
                              13607                 :              0 :         parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
                              13608         [ #  # ]:              0 :         for (i = 0; typeids[i]; i++)
                              13609                 :                :         {
                              13610         [ #  # ]:              0 :             if (i != 0)
                              13611                 :              0 :                 appendPQExpBufferStr(q, ", ");
                              13612                 :              0 :             appendPQExpBuffer(q, "FOR TYPE %s",
 2999 tgl@sss.pgh.pa.us       13613                 :              0 :                               getFormattedTypeName(fout, typeids[i], zeroAsNone));
                              13614                 :                :         }
                              13615                 :                : 
  269 dgustafsson@postgres    13616                 :              0 :         free(typeids);
                              13617                 :                :     }
                              13618                 :                : 
 2745 peter_e@gmx.net         13619         [ +  + ]:CBC        1811 :     if (prokind[0] == PROKIND_WINDOW)
 4310 heikki.linnakangas@i    13620                 :              5 :         appendPQExpBufferStr(q, " WINDOW");
                              13621                 :                : 
 8513 peter_e@gmx.net         13622         [ +  + ]:           1811 :     if (provolatile[0] != PROVOLATILE_VOLATILE)
                              13623                 :                :     {
 8520 tgl@sss.pgh.pa.us       13624         [ +  + ]:            363 :         if (provolatile[0] == PROVOLATILE_IMMUTABLE)
 4310 heikki.linnakangas@i    13625                 :            342 :             appendPQExpBufferStr(q, " IMMUTABLE");
 8520 tgl@sss.pgh.pa.us       13626         [ +  - ]:             21 :         else if (provolatile[0] == PROVOLATILE_STABLE)
 4310 heikki.linnakangas@i    13627                 :             21 :             appendPQExpBufferStr(q, " STABLE");
 8520 tgl@sss.pgh.pa.us       13628         [ #  # ]:UBC           0 :         else if (provolatile[0] != PROVOLATILE_VOLATILE)
 1247                         13629                 :              0 :             pg_fatal("unrecognized provolatile value for function \"%s\"",
                              13630                 :                :                      finfo->dobj.name);
                              13631                 :                :     }
                              13632                 :                : 
 8513 peter_e@gmx.net         13633         [ +  + ]:CBC        1811 :     if (proisstrict[0] == 't')
 4310 heikki.linnakangas@i    13634                 :            371 :         appendPQExpBufferStr(q, " STRICT");
                              13635                 :                : 
 8512 peter_e@gmx.net         13636         [ -  + ]:           1811 :     if (prosecdef[0] == 't')
 4310 heikki.linnakangas@i    13637                 :UBC           0 :         appendPQExpBufferStr(q, " SECURITY DEFINER");
                              13638                 :                : 
 4954 rhaas@postgresql.org    13639         [ +  + ]:CBC        1811 :     if (proleakproof[0] == 't')
 4310 heikki.linnakangas@i    13640                 :             10 :         appendPQExpBufferStr(q, " LEAKPROOF");
                              13641                 :                : 
                              13642                 :                :     /*
                              13643                 :                :      * COST and ROWS are emitted only if present and not default, so as not to
                              13644                 :                :      * break backwards-compatibility of the dump without need.  Keep this code
                              13645                 :                :      * in sync with the defaults in functioncmds.c.
                              13646                 :                :      */
 6802 tgl@sss.pgh.pa.us       13647         [ +  - ]:           1811 :     if (strcmp(procost, "0") != 0)
                              13648                 :                :     {
                              13649   [ +  +  +  + ]:           1811 :         if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
                              13650                 :                :         {
                              13651                 :                :             /* default cost is 1 */
                              13652         [ -  + ]:            391 :             if (strcmp(procost, "1") != 0)
 6802 tgl@sss.pgh.pa.us       13653                 :UBC           0 :                 appendPQExpBuffer(q, " COST %s", procost);
                              13654                 :                :         }
                              13655                 :                :         else
                              13656                 :                :         {
                              13657                 :                :             /* default cost is 100 */
 6802 tgl@sss.pgh.pa.us       13658         [ +  + ]:CBC        1420 :             if (strcmp(procost, "100") != 0)
                              13659                 :              6 :                 appendPQExpBuffer(q, " COST %s", procost);
                              13660                 :                :         }
                              13661                 :                :     }
                              13662         [ +  + ]:           1811 :     if (proretset[0] == 't' &&
                              13663   [ +  -  -  + ]:            193 :         strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
 6802 tgl@sss.pgh.pa.us       13664                 :UBC           0 :         appendPQExpBuffer(q, " ROWS %s", prorows);
                              13665                 :                : 
 2401 tgl@sss.pgh.pa.us       13666         [ +  + ]:CBC        1811 :     if (strcmp(prosupport, "-") != 0)
                              13667                 :                :     {
                              13668                 :                :         /* We rely on regprocout to provide quoting and qualification */
                              13669                 :             48 :         appendPQExpBuffer(q, " SUPPORT %s", prosupport);
                              13670                 :                :     }
                              13671                 :                : 
 1879 peter@eisentraut.org    13672         [ +  + ]:           1811 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              13673                 :                :     {
 3643 rhaas@postgresql.org    13674         [ +  + ]:            128 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              13675                 :            123 :             appendPQExpBufferStr(q, " PARALLEL SAFE");
                              13676         [ +  - ]:              5 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              13677                 :              5 :             appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
 3643 rhaas@postgresql.org    13678         [ #  # ]:UBC           0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
 1247 tgl@sss.pgh.pa.us       13679                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              13680                 :                :                      finfo->dobj.name);
                              13681                 :                :     }
                              13682                 :                : 
 1109 drowley@postgresql.o    13683         [ +  + ]:CBC        1846 :     for (int i = 0; i < nconfigitems; i++)
                              13684                 :                :     {
                              13685                 :                :         /* we feel free to scribble on configitems[] here */
 6578 tgl@sss.pgh.pa.us       13686                 :             35 :         char       *configitem = configitems[i];
                              13687                 :                :         char       *pos;
                              13688                 :                : 
                              13689                 :             35 :         pos = strchr(configitem, '=');
                              13690         [ -  + ]:             35 :         if (pos == NULL)
 6578 tgl@sss.pgh.pa.us       13691                 :UBC           0 :             continue;
 6578 tgl@sss.pgh.pa.us       13692                 :CBC          35 :         *pos++ = '\0';
                              13693                 :             35 :         appendPQExpBuffer(q, "\n    SET %s TO ", fmtId(configitem));
                              13694                 :                : 
                              13695                 :                :         /*
                              13696                 :                :          * Variables that are marked GUC_LIST_QUOTE were already fully quoted
                              13697                 :                :          * by flatten_set_variable_args() before they were put into the
                              13698                 :                :          * proconfig array.  However, because the quoting rules used there
                              13699                 :                :          * aren't exactly like SQL's, we have to break the list value apart
                              13700                 :                :          * and then quote the elements as string literals.  (The elements may
                              13701                 :                :          * be double-quoted as-is, but we can't just feed them to the SQL
                              13702                 :                :          * parser; it would do the wrong thing with elements that are
                              13703                 :                :          * zero-length or longer than NAMEDATALEN.)
                              13704                 :                :          *
                              13705                 :                :          * Variables that are not so marked should just be emitted as simple
                              13706                 :                :          * string literals.  If the variable is not known to
                              13707                 :                :          * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
                              13708                 :                :          * to use GUC_LIST_QUOTE for extension variables.
                              13709                 :                :          */
 2726                         13710         [ +  + ]:             35 :         if (variable_is_guc_list_quote(configitem))
                              13711                 :                :         {
                              13712                 :                :             char      **namelist;
                              13713                 :                :             char      **nameptr;
                              13714                 :                : 
                              13715                 :                :             /* Parse string into list of identifiers */
                              13716                 :                :             /* this shouldn't fail really */
 2594                         13717         [ +  - ]:             10 :             if (SplitGUCList(pos, ',', &namelist))
                              13718                 :                :             {
                              13719         [ +  + ]:             35 :                 for (nameptr = namelist; *nameptr; nameptr++)
                              13720                 :                :                 {
                              13721         [ +  + ]:             25 :                     if (nameptr != namelist)
                              13722                 :             15 :                         appendPQExpBufferStr(q, ", ");
                              13723                 :             25 :                     appendStringLiteralAH(q, *nameptr, fout);
                              13724                 :                :                 }
                              13725                 :                :             }
                              13726                 :             10 :             pg_free(namelist);
                              13727                 :                :         }
                              13728                 :                :         else
 6578                         13729                 :             25 :             appendStringLiteralAH(q, pos, fout);
                              13730                 :                :     }
                              13731                 :                : 
 6276 heikki.linnakangas@i    13732                 :           1811 :     appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
                              13733                 :                : 
 2005 alvherre@alvh.no-ip.    13734                 :           1811 :     append_depends_on_extension(fout, q, &finfo->dobj,
                              13735                 :                :                                 "pg_catalog.pg_proc", keyword,
                              13736                 :                :                                 qual_funcsig);
                              13737                 :                : 
 3980                         13738         [ +  + ]:           1811 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       13739                 :            288 :         binary_upgrade_extension_member(q, &finfo->dobj,
                              13740                 :                :                                         keyword, funcsig,
                              13741                 :            288 :                                         finfo->dobj.namespace->dobj.name);
                              13742                 :                : 
 3440 sfrost@snowman.net      13743         [ +  + ]:           1811 :     if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13744                 :           1703 :         ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13745         [ +  + ]:           1703 :                      ARCHIVE_OPTS(.tag = funcsig_tag,
                              13746                 :                :                                   .namespace = finfo->dobj.namespace->dobj.name,
                              13747                 :                :                                   .owner = finfo->rolname,
                              13748                 :                :                                   .description = keyword,
                              13749                 :                :                                   .section = finfo->postponed_def ?
                              13750                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              13751                 :                :                                   .createStmt = q->data,
                              13752                 :                :                                   .dropStmt = delqry->data));
                              13753                 :                : 
                              13754                 :                :     /* Dump Function Comments and Security Labels */
 3440 sfrost@snowman.net      13755         [ +  + ]:           1811 :     if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       13756                 :              9 :         dumpComment(fout, keyword, funcsig,
 3440 sfrost@snowman.net      13757                 :              9 :                     finfo->dobj.namespace->dobj.name, finfo->rolname,
                              13758                 :              9 :                     finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              13759                 :                : 
                              13760         [ -  + ]:           1811 :     if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       13761                 :UBC           0 :         dumpSecLabel(fout, keyword, funcsig,
 3440 sfrost@snowman.net      13762                 :              0 :                      finfo->dobj.namespace->dobj.name, finfo->rolname,
                              13763                 :              0 :                      finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              13764                 :                : 
 3440 sfrost@snowman.net      13765         [ +  + ]:CBC        1811 :     if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       13766                 :            112 :         dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
                              13767                 :                :                 funcsig, NULL,
 3440 sfrost@snowman.net      13768                 :            112 :                 finfo->dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       13769                 :            112 :                 NULL, finfo->rolname, &finfo->dacl);
                              13770                 :                : 
 8520                         13771                 :           1811 :     PQclear(res);
                              13772                 :                : 
                              13773                 :           1811 :     destroyPQExpBuffer(query);
 8800                         13774                 :           1811 :     destroyPQExpBuffer(q);
                              13775                 :           1811 :     destroyPQExpBuffer(delqry);
                              13776                 :           1811 :     destroyPQExpBuffer(asPart);
 8511 peter_e@gmx.net         13777                 :           1811 :     free(funcsig);
 1178 peter@eisentraut.org    13778                 :           1811 :     free(funcfullsig);
 8465 bruce@momjian.us        13779                 :           1811 :     free(funcsig_tag);
 1413 tgl@sss.pgh.pa.us       13780                 :           1811 :     free(qual_funcsig);
 1178 peter@eisentraut.org    13781                 :           1811 :     free(configitems);
                              13782                 :                : }
                              13783                 :                : 
                              13784                 :                : 
                              13785                 :                : /*
                              13786                 :                :  * Dump a user-defined cast
                              13787                 :                :  */
                              13788                 :                : static void
 1669                         13789                 :             73 : dumpCast(Archive *fout, const CastInfo *cast)
                              13790                 :                : {
 3524 tgl@sss.pgh.pa.us       13791                 :             73 :     DumpOptions *dopt = fout->dopt;
                              13792                 :                :     PQExpBuffer defqry;
                              13793                 :                :     PQExpBuffer delqry;
                              13794                 :                :     PQExpBuffer labelq;
                              13795                 :                :     PQExpBuffer castargs;
 7945                         13796                 :             73 :     FuncInfo   *funcInfo = NULL;
                              13797                 :                :     const char *sourceType;
                              13798                 :                :     const char *targetType;
                              13799                 :                : 
                              13800                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    13801         [ +  + ]:             73 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       13802                 :              6 :         return;
                              13803                 :                : 
                              13804                 :                :     /* Cannot dump if we don't have the cast function's info */
                              13805         [ +  + ]:             67 :     if (OidIsValid(cast->castfunc))
                              13806                 :                :     {
                              13807                 :             42 :         funcInfo = findFuncByOid(cast->castfunc);
                              13808         [ -  + ]:             42 :         if (funcInfo == NULL)
 1247 tgl@sss.pgh.pa.us       13809                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13810                 :                :                      cast->castfunc);
                              13811                 :                :     }
                              13812                 :                : 
 7945 tgl@sss.pgh.pa.us       13813                 :CBC          67 :     defqry = createPQExpBuffer();
                              13814                 :             67 :     delqry = createPQExpBuffer();
 5323                         13815                 :             67 :     labelq = createPQExpBuffer();
 2749                         13816                 :             67 :     castargs = createPQExpBuffer();
                              13817                 :                : 
 3719 heikki.linnakangas@i    13818                 :             67 :     sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
                              13819                 :             67 :     targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
 7945 tgl@sss.pgh.pa.us       13820                 :             67 :     appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
                              13821                 :                :                       sourceType, targetType);
                              13822                 :                : 
                              13823                 :             67 :     appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
                              13824                 :                :                       sourceType, targetType);
                              13825                 :                : 
 5931 bruce@momjian.us        13826   [ +  -  +  - ]:             67 :     switch (cast->castmethod)
                              13827                 :                :     {
 6154 heikki.linnakangas@i    13828                 :             25 :         case COERCION_METHOD_BINARY:
 4310                         13829                 :             25 :             appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
 6154                         13830                 :             25 :             break;
 6154 heikki.linnakangas@i    13831                 :UBC           0 :         case COERCION_METHOD_INOUT:
 4310                         13832                 :              0 :             appendPQExpBufferStr(defqry, "WITH INOUT");
 6154                         13833                 :              0 :             break;
 6154 heikki.linnakangas@i    13834                 :CBC          42 :         case COERCION_METHOD_FUNCTION:
 4922 peter_e@gmx.net         13835         [ +  - ]:             42 :             if (funcInfo)
                              13836                 :                :             {
 4836 bruce@momjian.us        13837                 :             42 :                 char       *fsig = format_function_signature(fout, funcInfo, true);
                              13838                 :                : 
                              13839                 :                :                 /*
                              13840                 :                :                  * Always qualify the function name (format_function_signature
                              13841                 :                :                  * won't qualify it).
                              13842                 :                :                  */
 4922 peter_e@gmx.net         13843                 :             42 :                 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
 2999 tgl@sss.pgh.pa.us       13844                 :             42 :                                   fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
 4922 peter_e@gmx.net         13845                 :             42 :                 free(fsig);
                              13846                 :                :             }
                              13847                 :                :             else
 2350 peter@eisentraut.org    13848                 :UBC           0 :                 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
 6154 heikki.linnakangas@i    13849                 :CBC          42 :             break;
 6154 heikki.linnakangas@i    13850                 :UBC           0 :         default:
 2350 peter@eisentraut.org    13851                 :              0 :             pg_log_warning("bogus value in pg_cast.castmethod field");
                              13852                 :                :     }
                              13853                 :                : 
 7945 tgl@sss.pgh.pa.us       13854         [ +  + ]:CBC          67 :     if (cast->castcontext == 'a')
 4310 heikki.linnakangas@i    13855                 :             37 :         appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
 7945 tgl@sss.pgh.pa.us       13856         [ +  + ]:             30 :     else if (cast->castcontext == 'i')
 4310 heikki.linnakangas@i    13857                 :             10 :         appendPQExpBufferStr(defqry, " AS IMPLICIT");
                              13858                 :             67 :     appendPQExpBufferStr(defqry, ";\n");
                              13859                 :                : 
 5323 tgl@sss.pgh.pa.us       13860                 :             67 :     appendPQExpBuffer(labelq, "CAST (%s AS %s)",
                              13861                 :                :                       sourceType, targetType);
                              13862                 :                : 
 2749                         13863                 :             67 :     appendPQExpBuffer(castargs, "(%s AS %s)",
                              13864                 :                :                       sourceType, targetType);
                              13865                 :                : 
 3980 alvherre@alvh.no-ip.    13866         [ +  + ]:             67 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       13867                 :              7 :         binary_upgrade_extension_member(defqry, &cast->dobj,
                              13868                 :              7 :                                         "CAST", castargs->data, NULL);
                              13869                 :                : 
 3440 sfrost@snowman.net      13870         [ +  - ]:             67 :     if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13871                 :             67 :         ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13872                 :             67 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              13873                 :                :                                   .description = "CAST",
                              13874                 :                :                                   .section = SECTION_PRE_DATA,
                              13875                 :                :                                   .createStmt = defqry->data,
                              13876                 :                :                                   .dropStmt = delqry->data));
                              13877                 :                : 
                              13878                 :                :     /* Dump Cast Comments */
 3440 sfrost@snowman.net      13879         [ -  + ]:             67 :     if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       13880                 :UBC           0 :         dumpComment(fout, "CAST", castargs->data,
                              13881                 :                :                     NULL, "",
 3440 sfrost@snowman.net      13882                 :              0 :                     cast->dobj.catId, 0, cast->dobj.dumpId);
                              13883                 :                : 
 8451 peter_e@gmx.net         13884                 :CBC          67 :     destroyPQExpBuffer(defqry);
                              13885                 :             67 :     destroyPQExpBuffer(delqry);
 5323 tgl@sss.pgh.pa.us       13886                 :             67 :     destroyPQExpBuffer(labelq);
 2749                         13887                 :             67 :     destroyPQExpBuffer(castargs);
                              13888                 :                : }
                              13889                 :                : 
                              13890                 :                : /*
                              13891                 :                :  * Dump a transform
                              13892                 :                :  */
                              13893                 :                : static void
 1669 peter@eisentraut.org    13894                 :             48 : dumpTransform(Archive *fout, const TransformInfo *transform)
                              13895                 :                : {
 3524 tgl@sss.pgh.pa.us       13896                 :             48 :     DumpOptions *dopt = fout->dopt;
                              13897                 :                :     PQExpBuffer defqry;
                              13898                 :                :     PQExpBuffer delqry;
                              13899                 :                :     PQExpBuffer labelq;
                              13900                 :                :     PQExpBuffer transformargs;
 3786 peter_e@gmx.net         13901                 :             48 :     FuncInfo   *fromsqlFuncInfo = NULL;
                              13902                 :             48 :     FuncInfo   *tosqlFuncInfo = NULL;
                              13903                 :                :     char       *lanname;
                              13904                 :                :     const char *transformType;
                              13905                 :                : 
                              13906                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    13907         [ +  + ]:             48 :     if (!dopt->dumpSchema)
 3786 peter_e@gmx.net         13908                 :              6 :         return;
                              13909                 :                : 
                              13910                 :                :     /* Cannot dump if we don't have the transform functions' info */
                              13911         [ +  - ]:             42 :     if (OidIsValid(transform->trffromsql))
                              13912                 :                :     {
                              13913                 :             42 :         fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
                              13914         [ -  + ]:             42 :         if (fromsqlFuncInfo == NULL)
 1247 tgl@sss.pgh.pa.us       13915                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13916                 :                :                      transform->trffromsql);
                              13917                 :                :     }
 3786 peter_e@gmx.net         13918         [ +  - ]:CBC          42 :     if (OidIsValid(transform->trftosql))
                              13919                 :                :     {
                              13920                 :             42 :         tosqlFuncInfo = findFuncByOid(transform->trftosql);
                              13921         [ -  + ]:             42 :         if (tosqlFuncInfo == NULL)
 1247 tgl@sss.pgh.pa.us       13922                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              13923                 :                :                      transform->trftosql);
                              13924                 :                :     }
                              13925                 :                : 
 3786 peter_e@gmx.net         13926                 :CBC          42 :     defqry = createPQExpBuffer();
                              13927                 :             42 :     delqry = createPQExpBuffer();
                              13928                 :             42 :     labelq = createPQExpBuffer();
 2749 tgl@sss.pgh.pa.us       13929                 :             42 :     transformargs = createPQExpBuffer();
                              13930                 :                : 
 3786 peter_e@gmx.net         13931                 :             42 :     lanname = get_language_name(fout, transform->trflang);
 3719 heikki.linnakangas@i    13932                 :             42 :     transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
                              13933                 :                : 
 3786 peter_e@gmx.net         13934                 :             42 :     appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
                              13935                 :                :                       transformType, lanname);
                              13936                 :                : 
                              13937                 :             42 :     appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
                              13938                 :                :                       transformType, lanname);
                              13939                 :                : 
                              13940   [ -  +  -  - ]:             42 :     if (!transform->trffromsql && !transform->trftosql)
 2350 peter@eisentraut.org    13941                 :UBC           0 :         pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
                              13942                 :                : 
 3786 peter_e@gmx.net         13943         [ +  - ]:CBC          42 :     if (transform->trffromsql)
                              13944                 :                :     {
                              13945         [ +  - ]:             42 :         if (fromsqlFuncInfo)
                              13946                 :                :         {
                              13947                 :             42 :             char       *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
                              13948                 :                : 
                              13949                 :                :             /*
                              13950                 :                :              * Always qualify the function name (format_function_signature
                              13951                 :                :              * won't qualify it).
                              13952                 :                :              */
                              13953                 :             42 :             appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
 2999 tgl@sss.pgh.pa.us       13954                 :             42 :                               fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3786 peter_e@gmx.net         13955                 :             42 :             free(fsig);
                              13956                 :                :         }
                              13957                 :                :         else
 2350 peter@eisentraut.org    13958                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trffromsql field");
                              13959                 :                :     }
                              13960                 :                : 
 3786 peter_e@gmx.net         13961         [ +  - ]:CBC          42 :     if (transform->trftosql)
                              13962                 :                :     {
                              13963         [ +  - ]:             42 :         if (transform->trffromsql)
 2256 drowley@postgresql.o    13964                 :             42 :             appendPQExpBufferStr(defqry, ", ");
                              13965                 :                : 
 3786 peter_e@gmx.net         13966         [ +  - ]:             42 :         if (tosqlFuncInfo)
                              13967                 :                :         {
                              13968                 :             42 :             char       *fsig = format_function_signature(fout, tosqlFuncInfo, true);
                              13969                 :                : 
                              13970                 :                :             /*
                              13971                 :                :              * Always qualify the function name (format_function_signature
                              13972                 :                :              * won't qualify it).
                              13973                 :                :              */
                              13974                 :             42 :             appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
 2999 tgl@sss.pgh.pa.us       13975                 :             42 :                               fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3786 peter_e@gmx.net         13976                 :             42 :             free(fsig);
                              13977                 :                :         }
                              13978                 :                :         else
 2350 peter@eisentraut.org    13979                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trftosql field");
                              13980                 :                :     }
                              13981                 :                : 
 2256 drowley@postgresql.o    13982                 :CBC          42 :     appendPQExpBufferStr(defqry, ");\n");
                              13983                 :                : 
 3786 peter_e@gmx.net         13984                 :             42 :     appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
                              13985                 :                :                       transformType, lanname);
                              13986                 :                : 
 2749 tgl@sss.pgh.pa.us       13987                 :             42 :     appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
                              13988                 :                :                       transformType, lanname);
                              13989                 :                : 
 3786 peter_e@gmx.net         13990         [ +  + ]:             42 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       13991                 :              2 :         binary_upgrade_extension_member(defqry, &transform->dobj,
                              13992                 :              2 :                                         "TRANSFORM", transformargs->data, NULL);
                              13993                 :                : 
 3440 sfrost@snowman.net      13994         [ +  - ]:             42 :     if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13995                 :             42 :         ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    13996                 :             42 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              13997                 :                :                                   .description = "TRANSFORM",
                              13998                 :                :                                   .section = SECTION_PRE_DATA,
                              13999                 :                :                                   .createStmt = defqry->data,
                              14000                 :                :                                   .dropStmt = delqry->data,
                              14001                 :                :                                   .deps = transform->dobj.dependencies,
                              14002                 :                :                                   .nDeps = transform->dobj.nDeps));
                              14003                 :                : 
                              14004                 :                :     /* Dump Transform Comments */
 3440 sfrost@snowman.net      14005         [ -  + ]:             42 :     if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       14006                 :UBC           0 :         dumpComment(fout, "TRANSFORM", transformargs->data,
                              14007                 :                :                     NULL, "",
 3440 sfrost@snowman.net      14008                 :              0 :                     transform->dobj.catId, 0, transform->dobj.dumpId);
                              14009                 :                : 
 3786 peter_e@gmx.net         14010                 :CBC          42 :     free(lanname);
                              14011                 :             42 :     destroyPQExpBuffer(defqry);
                              14012                 :             42 :     destroyPQExpBuffer(delqry);
                              14013                 :             42 :     destroyPQExpBuffer(labelq);
 2749 tgl@sss.pgh.pa.us       14014                 :             42 :     destroyPQExpBuffer(transformargs);
                              14015                 :                : }
                              14016                 :                : 
                              14017                 :                : 
                              14018                 :                : /*
                              14019                 :                :  * dumpOpr
                              14020                 :                :  *    write out a single operator definition
                              14021                 :                :  */
                              14022                 :                : static void
 1669 peter@eisentraut.org    14023                 :           2510 : dumpOpr(Archive *fout, const OprInfo *oprinfo)
                              14024                 :                : {
 3524 tgl@sss.pgh.pa.us       14025                 :           2510 :     DumpOptions *dopt = fout->dopt;
                              14026                 :                :     PQExpBuffer query;
                              14027                 :                :     PQExpBuffer q;
                              14028                 :                :     PQExpBuffer delq;
                              14029                 :                :     PQExpBuffer oprid;
                              14030                 :                :     PQExpBuffer details;
                              14031                 :                :     PGresult   *res;
                              14032                 :                :     int         i_oprkind;
                              14033                 :                :     int         i_oprcode;
                              14034                 :                :     int         i_oprleft;
                              14035                 :                :     int         i_oprright;
                              14036                 :                :     int         i_oprcom;
                              14037                 :                :     int         i_oprnegate;
                              14038                 :                :     int         i_oprrest;
                              14039                 :                :     int         i_oprjoin;
                              14040                 :                :     int         i_oprcanmerge;
                              14041                 :                :     int         i_oprcanhash;
                              14042                 :                :     char       *oprkind;
                              14043                 :                :     char       *oprcode;
                              14044                 :                :     char       *oprleft;
                              14045                 :                :     char       *oprright;
                              14046                 :                :     char       *oprcom;
                              14047                 :                :     char       *oprnegate;
                              14048                 :                :     char       *oprrest;
                              14049                 :                :     char       *oprjoin;
                              14050                 :                :     char       *oprcanmerge;
                              14051                 :                :     char       *oprcanhash;
                              14052                 :                :     char       *oprregproc;
                              14053                 :                :     char       *oprref;
                              14054                 :                : 
                              14055                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    14056         [ +  + ]:           2510 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       14057                 :              6 :         return;
                              14058                 :                : 
                              14059                 :                :     /*
                              14060                 :                :      * some operators are invalid because they were the result of user
                              14061                 :                :      * defining operators before commutators exist
                              14062                 :                :      */
                              14063         [ +  + ]:           2504 :     if (!OidIsValid(oprinfo->oprcode))
                              14064                 :             14 :         return;
                              14065                 :                : 
                              14066                 :           2490 :     query = createPQExpBuffer();
                              14067                 :           2490 :     q = createPQExpBuffer();
                              14068                 :           2490 :     delq = createPQExpBuffer();
                              14069                 :           2490 :     oprid = createPQExpBuffer();
                              14070                 :           2490 :     details = createPQExpBuffer();
                              14071                 :                : 
 1370                         14072         [ +  + ]:           2490 :     if (!fout->is_prepared[PREPQUERY_DUMPOPR])
                              14073                 :                :     {
                              14074                 :                :         /* Set up query for operator-specific details */
                              14075                 :             46 :         appendPQExpBufferStr(query,
                              14076                 :                :                              "PREPARE dumpOpr(pg_catalog.oid) AS\n"
                              14077                 :                :                              "SELECT oprkind, "
                              14078                 :                :                              "oprcode::pg_catalog.regprocedure, "
                              14079                 :                :                              "oprleft::pg_catalog.regtype, "
                              14080                 :                :                              "oprright::pg_catalog.regtype, "
                              14081                 :                :                              "oprcom, "
                              14082                 :                :                              "oprnegate, "
                              14083                 :                :                              "oprrest::pg_catalog.regprocedure, "
                              14084                 :                :                              "oprjoin::pg_catalog.regprocedure, "
                              14085                 :                :                              "oprcanmerge, oprcanhash "
                              14086                 :                :                              "FROM pg_catalog.pg_operator "
                              14087                 :                :                              "WHERE oid = $1");
                              14088                 :                : 
                              14089                 :             46 :         ExecuteSqlStatement(fout, query->data);
                              14090                 :                : 
                              14091                 :             46 :         fout->is_prepared[PREPQUERY_DUMPOPR] = true;
                              14092                 :                :     }
                              14093                 :                : 
                              14094                 :           2490 :     printfPQExpBuffer(query,
                              14095                 :                :                       "EXECUTE dumpOpr('%u')",
                              14096                 :           2490 :                       oprinfo->dobj.catId.oid);
                              14097                 :                : 
 4951 rhaas@postgresql.org    14098                 :           2490 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14099                 :                : 
 8520 tgl@sss.pgh.pa.us       14100                 :           2490 :     i_oprkind = PQfnumber(res, "oprkind");
                              14101                 :           2490 :     i_oprcode = PQfnumber(res, "oprcode");
                              14102                 :           2490 :     i_oprleft = PQfnumber(res, "oprleft");
                              14103                 :           2490 :     i_oprright = PQfnumber(res, "oprright");
                              14104                 :           2490 :     i_oprcom = PQfnumber(res, "oprcom");
                              14105                 :           2490 :     i_oprnegate = PQfnumber(res, "oprnegate");
                              14106                 :           2490 :     i_oprrest = PQfnumber(res, "oprrest");
                              14107                 :           2490 :     i_oprjoin = PQfnumber(res, "oprjoin");
 6832                         14108                 :           2490 :     i_oprcanmerge = PQfnumber(res, "oprcanmerge");
 8520                         14109                 :           2490 :     i_oprcanhash = PQfnumber(res, "oprcanhash");
                              14110                 :                : 
                              14111                 :           2490 :     oprkind = PQgetvalue(res, 0, i_oprkind);
                              14112                 :           2490 :     oprcode = PQgetvalue(res, 0, i_oprcode);
                              14113                 :           2490 :     oprleft = PQgetvalue(res, 0, i_oprleft);
                              14114                 :           2490 :     oprright = PQgetvalue(res, 0, i_oprright);
                              14115                 :           2490 :     oprcom = PQgetvalue(res, 0, i_oprcom);
                              14116                 :           2490 :     oprnegate = PQgetvalue(res, 0, i_oprnegate);
                              14117                 :           2490 :     oprrest = PQgetvalue(res, 0, i_oprrest);
                              14118                 :           2490 :     oprjoin = PQgetvalue(res, 0, i_oprjoin);
 6832                         14119                 :           2490 :     oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
 8520                         14120                 :           2490 :     oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
                              14121                 :                : 
                              14122                 :                :     /* In PG14 upwards postfix operator support does not exist anymore. */
 1815                         14123         [ -  + ]:           2490 :     if (strcmp(oprkind, "r") == 0)
 1815 tgl@sss.pgh.pa.us       14124                 :UBC           0 :         pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
                              14125                 :                :                        oprcode);
                              14126                 :                : 
 1838 peter@eisentraut.org    14127                 :CBC        2490 :     oprregproc = convertRegProcReference(oprcode);
 4207 sfrost@snowman.net      14128         [ +  - ]:           2490 :     if (oprregproc)
                              14129                 :                :     {
 2579 peter_e@gmx.net         14130                 :           2490 :         appendPQExpBuffer(details, "    FUNCTION = %s", oprregproc);
 4207 sfrost@snowman.net      14131                 :           2490 :         free(oprregproc);
                              14132                 :                :     }
                              14133                 :                : 
 8520 tgl@sss.pgh.pa.us       14134                 :           2490 :     appendPQExpBuffer(oprid, "%s (",
 7857                         14135                 :           2490 :                       oprinfo->dobj.name);
                              14136                 :                : 
                              14137                 :                :     /*
                              14138                 :                :      * right unary means there's a left arg and left unary means there's a
                              14139                 :                :      * right arg.  (Although the "r" case is dead code for PG14 and later,
                              14140                 :                :      * continue to support it in case we're dumping from an old server.)
                              14141                 :                :      */
 8520                         14142         [ +  - ]:           2490 :     if (strcmp(oprkind, "r") == 0 ||
                              14143         [ +  + ]:           2490 :         strcmp(oprkind, "b") == 0)
                              14144                 :                :     {
 3251                         14145                 :           2347 :         appendPQExpBuffer(details, ",\n    LEFTARG = %s", oprleft);
                              14146                 :           2347 :         appendPQExpBufferStr(oprid, oprleft);
                              14147                 :                :     }
                              14148                 :                :     else
 4310 heikki.linnakangas@i    14149                 :            143 :         appendPQExpBufferStr(oprid, "NONE");
                              14150                 :                : 
 8520 tgl@sss.pgh.pa.us       14151         [ +  + ]:           2490 :     if (strcmp(oprkind, "l") == 0 ||
                              14152         [ +  - ]:           2347 :         strcmp(oprkind, "b") == 0)
                              14153                 :                :     {
 3251                         14154                 :           2490 :         appendPQExpBuffer(details, ",\n    RIGHTARG = %s", oprright);
                              14155                 :           2490 :         appendPQExpBuffer(oprid, ", %s)", oprright);
                              14156                 :                :     }
                              14157                 :                :     else
 4310 heikki.linnakangas@i    14158                 :UBC           0 :         appendPQExpBufferStr(oprid, ", NONE)");
                              14159                 :                : 
 1838 peter@eisentraut.org    14160                 :CBC        2490 :     oprref = getFormattedOperatorName(oprcom);
 4207 sfrost@snowman.net      14161         [ +  + ]:           2490 :     if (oprref)
                              14162                 :                :     {
                              14163                 :           1661 :         appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
                              14164                 :           1661 :         free(oprref);
                              14165                 :                :     }
                              14166                 :                : 
 1838 peter@eisentraut.org    14167                 :           2490 :     oprref = getFormattedOperatorName(oprnegate);
 4207 sfrost@snowman.net      14168         [ +  + ]:           2490 :     if (oprref)
                              14169                 :                :     {
                              14170                 :           1163 :         appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
                              14171                 :           1163 :         free(oprref);
                              14172                 :                :     }
                              14173                 :                : 
 6832 tgl@sss.pgh.pa.us       14174         [ +  + ]:           2490 :     if (strcmp(oprcanmerge, "t") == 0)
 4310 heikki.linnakangas@i    14175                 :            185 :         appendPQExpBufferStr(details, ",\n    MERGES");
                              14176                 :                : 
 8520 tgl@sss.pgh.pa.us       14177         [ +  + ]:           2490 :     if (strcmp(oprcanhash, "t") == 0)
 4310 heikki.linnakangas@i    14178                 :            138 :         appendPQExpBufferStr(details, ",\n    HASHES");
                              14179                 :                : 
 1838 peter@eisentraut.org    14180                 :           2490 :     oprregproc = convertRegProcReference(oprrest);
 4207 sfrost@snowman.net      14181         [ +  + ]:           2490 :     if (oprregproc)
                              14182                 :                :     {
                              14183                 :           1514 :         appendPQExpBuffer(details, ",\n    RESTRICT = %s", oprregproc);
                              14184                 :           1514 :         free(oprregproc);
                              14185                 :                :     }
                              14186                 :                : 
 1838 peter@eisentraut.org    14187                 :           2490 :     oprregproc = convertRegProcReference(oprjoin);
 4207 sfrost@snowman.net      14188         [ +  + ]:           2490 :     if (oprregproc)
                              14189                 :                :     {
                              14190                 :           1514 :         appendPQExpBuffer(details, ",\n    JOIN = %s", oprregproc);
                              14191                 :           1514 :         free(oprregproc);
                              14192                 :                :     }
                              14193                 :                : 
 8502 tgl@sss.pgh.pa.us       14194                 :           2490 :     appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
 7857                         14195                 :           2490 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
                              14196                 :                :                       oprid->data);
                              14197                 :                : 
 2749                         14198                 :           2490 :     appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
                              14199                 :           2490 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
 7857                         14200                 :           2490 :                       oprinfo->dobj.name, details->data);
                              14201                 :                : 
 3980 alvherre@alvh.no-ip.    14202         [ +  + ]:           2490 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       14203                 :             12 :         binary_upgrade_extension_member(q, &oprinfo->dobj,
                              14204                 :             12 :                                         "OPERATOR", oprid->data,
                              14205                 :             12 :                                         oprinfo->dobj.namespace->dobj.name);
                              14206                 :                : 
 3440 sfrost@snowman.net      14207         [ +  - ]:           2490 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14208                 :           2490 :         ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    14209                 :           2490 :                      ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
                              14210                 :                :                                   .namespace = oprinfo->dobj.namespace->dobj.name,
                              14211                 :                :                                   .owner = oprinfo->rolname,
                              14212                 :                :                                   .description = "OPERATOR",
                              14213                 :                :                                   .section = SECTION_PRE_DATA,
                              14214                 :                :                                   .createStmt = q->data,
                              14215                 :                :                                   .dropStmt = delq->data));
                              14216                 :                : 
                              14217                 :                :     /* Dump Operator Comments */
 3440 sfrost@snowman.net      14218         [ +  + ]:           2490 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       14219                 :           2397 :         dumpComment(fout, "OPERATOR", oprid->data,
 3440 sfrost@snowman.net      14220                 :           2397 :                     oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                              14221                 :           2397 :                     oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
                              14222                 :                : 
 8520 tgl@sss.pgh.pa.us       14223                 :           2490 :     PQclear(res);
                              14224                 :                : 
                              14225                 :           2490 :     destroyPQExpBuffer(query);
                              14226                 :           2490 :     destroyPQExpBuffer(q);
                              14227                 :           2490 :     destroyPQExpBuffer(delq);
                              14228                 :           2490 :     destroyPQExpBuffer(oprid);
                              14229                 :           2490 :     destroyPQExpBuffer(details);
                              14230                 :                : }
                              14231                 :                : 
                              14232                 :                : /*
                              14233                 :                :  * Convert a function reference obtained from pg_operator
                              14234                 :                :  *
                              14235                 :                :  * Returns allocated string of what to print, or NULL if function references
                              14236                 :                :  * is InvalidOid. Returned string is expected to be free'd by the caller.
                              14237                 :                :  *
                              14238                 :                :  * The input is a REGPROCEDURE display; we have to strip the argument-types
                              14239                 :                :  * part.
                              14240                 :                :  */
                              14241                 :                : static char *
 1838 peter@eisentraut.org    14242                 :           7470 : convertRegProcReference(const char *proc)
                              14243                 :                : {
                              14244                 :                :     char       *name;
                              14245                 :                :     char       *paren;
                              14246                 :                :     bool        inquote;
                              14247                 :                : 
                              14248                 :                :     /* In all cases "-" means a null reference */
 8520 tgl@sss.pgh.pa.us       14249         [ +  + ]:           7470 :     if (strcmp(proc, "-") == 0)
                              14250                 :           1952 :         return NULL;
                              14251                 :                : 
 3251                         14252                 :           5518 :     name = pg_strdup(proc);
                              14253                 :                :     /* find non-double-quoted left paren */
                              14254                 :           5518 :     inquote = false;
                              14255         [ +  - ]:          66474 :     for (paren = name; *paren; paren++)
                              14256                 :                :     {
                              14257   [ +  +  +  - ]:          66474 :         if (*paren == '(' && !inquote)
                              14258                 :                :         {
                              14259                 :           5518 :             *paren = '\0';
                              14260                 :           5518 :             break;
                              14261                 :                :         }
                              14262         [ +  + ]:          60956 :         if (*paren == '"')
                              14263                 :             50 :             inquote = !inquote;
                              14264                 :                :     }
                              14265                 :           5518 :     return name;
                              14266                 :                : }
                              14267                 :                : 
                              14268                 :                : /*
                              14269                 :                :  * getFormattedOperatorName - retrieve the operator name for the
                              14270                 :                :  * given operator OID (presented in string form).
                              14271                 :                :  *
                              14272                 :                :  * Returns an allocated string, or NULL if the given OID is invalid.
                              14273                 :                :  * Caller is responsible for free'ing result string.
                              14274                 :                :  *
                              14275                 :                :  * What we produce has the format "OPERATOR(schema.oprname)".  This is only
                              14276                 :                :  * useful in commands where the operator's argument types can be inferred from
                              14277                 :                :  * context.  We always schema-qualify the name, though.  The predecessor to
                              14278                 :                :  * this code tried to skip the schema qualification if possible, but that led
                              14279                 :                :  * to wrong results in corner cases, such as if an operator and its negator
                              14280                 :                :  * are in different schemas.
                              14281                 :                :  */
                              14282                 :                : static char *
 1838 peter@eisentraut.org    14283                 :           5271 : getFormattedOperatorName(const char *oproid)
                              14284                 :                : {
                              14285                 :                :     OprInfo    *oprInfo;
                              14286                 :                : 
                              14287                 :                :     /* In all cases "0" means a null reference */
 2749 tgl@sss.pgh.pa.us       14288         [ +  + ]:           5271 :     if (strcmp(oproid, "0") == 0)
 8520                         14289                 :           2447 :         return NULL;
                              14290                 :                : 
 2749                         14291                 :           2824 :     oprInfo = findOprByOid(atooid(oproid));
                              14292         [ -  + ]:           2824 :     if (oprInfo == NULL)
                              14293                 :                :     {
 2350 peter@eisentraut.org    14294                 :UBC           0 :         pg_log_warning("could not find operator with OID %s",
                              14295                 :                :                        oproid);
 2749 tgl@sss.pgh.pa.us       14296                 :              0 :         return NULL;
                              14297                 :                :     }
                              14298                 :                : 
 2749 tgl@sss.pgh.pa.us       14299                 :CBC        2824 :     return psprintf("OPERATOR(%s.%s)",
                              14300                 :           2824 :                     fmtId(oprInfo->dobj.namespace->dobj.name),
                              14301                 :                :                     oprInfo->dobj.name);
                              14302                 :                : }
                              14303                 :                : 
                              14304                 :                : /*
                              14305                 :                :  * Convert a function OID obtained from pg_ts_parser or pg_ts_template
                              14306                 :                :  *
                              14307                 :                :  * It is sufficient to use REGPROC rather than REGPROCEDURE, since the
                              14308                 :                :  * argument lists of these functions are predetermined.  Note that the
                              14309                 :                :  * caller should ensure we are in the proper schema, because the results
                              14310                 :                :  * are search path dependent!
                              14311                 :                :  */
                              14312                 :                : static char *
 4960 rhaas@postgresql.org    14313                 :            235 : convertTSFunction(Archive *fout, Oid funcOid)
                              14314                 :                : {
                              14315                 :                :     char       *result;
                              14316                 :                :     char        query[128];
                              14317                 :                :     PGresult   *res;
                              14318                 :                : 
 6591 tgl@sss.pgh.pa.us       14319                 :            235 :     snprintf(query, sizeof(query),
                              14320                 :                :              "SELECT '%u'::pg_catalog.regproc", funcOid);
 4951 rhaas@postgresql.org    14321                 :            235 :     res = ExecuteSqlQueryForSingleRow(fout, query);
                              14322                 :                : 
 5034 bruce@momjian.us        14323                 :            235 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              14324                 :                : 
 6591 tgl@sss.pgh.pa.us       14325                 :            235 :     PQclear(res);
                              14326                 :                : 
                              14327                 :            235 :     return result;
                              14328                 :                : }
                              14329                 :                : 
                              14330                 :                : /*
                              14331                 :                :  * dumpAccessMethod
                              14332                 :                :  *    write out a single access method definition
                              14333                 :                :  */
                              14334                 :                : static void
 1669 peter@eisentraut.org    14335                 :             92 : dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
                              14336                 :                : {
 3454 alvherre@alvh.no-ip.    14337                 :             92 :     DumpOptions *dopt = fout->dopt;
                              14338                 :                :     PQExpBuffer q;
                              14339                 :                :     PQExpBuffer delq;
                              14340                 :                :     char       *qamname;
                              14341                 :                : 
                              14342                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    14343         [ +  + ]:             92 :     if (!dopt->dumpSchema)
 3454 alvherre@alvh.no-ip.    14344                 :             12 :         return;
                              14345                 :                : 
                              14346                 :             80 :     q = createPQExpBuffer();
                              14347                 :             80 :     delq = createPQExpBuffer();
                              14348                 :                : 
                              14349                 :             80 :     qamname = pg_strdup(fmtId(aminfo->dobj.name));
                              14350                 :                : 
                              14351                 :             80 :     appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
                              14352                 :                : 
                              14353      [ +  +  - ]:             80 :     switch (aminfo->amtype)
                              14354                 :                :     {
                              14355                 :             38 :         case AMTYPE_INDEX:
 2256 drowley@postgresql.o    14356                 :             38 :             appendPQExpBufferStr(q, "TYPE INDEX ");
 3454 alvherre@alvh.no-ip.    14357                 :             38 :             break;
 2376 andres@anarazel.de      14358                 :             42 :         case AMTYPE_TABLE:
 2256 drowley@postgresql.o    14359                 :             42 :             appendPQExpBufferStr(q, "TYPE TABLE ");
 2376 andres@anarazel.de      14360                 :             42 :             break;
 3454 alvherre@alvh.no-ip.    14361                 :UBC           0 :         default:
 2350 peter@eisentraut.org    14362                 :              0 :             pg_log_warning("invalid type \"%c\" of access method \"%s\"",
                              14363                 :                :                            aminfo->amtype, qamname);
 3454 alvherre@alvh.no-ip.    14364                 :              0 :             destroyPQExpBuffer(q);
                              14365                 :              0 :             destroyPQExpBuffer(delq);
 2749 tgl@sss.pgh.pa.us       14366                 :              0 :             free(qamname);
 3454 alvherre@alvh.no-ip.    14367                 :              0 :             return;
                              14368                 :                :     }
                              14369                 :                : 
 3454 alvherre@alvh.no-ip.    14370                 :CBC          80 :     appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
                              14371                 :                : 
                              14372                 :             80 :     appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
                              14373                 :                :                       qamname);
                              14374                 :                : 
 3261 tgl@sss.pgh.pa.us       14375         [ +  + ]:             80 :     if (dopt->binary_upgrade)
 2749                         14376                 :              4 :         binary_upgrade_extension_member(q, &aminfo->dobj,
                              14377                 :                :                                         "ACCESS METHOD", qamname, NULL);
                              14378                 :                : 
 3378 sfrost@snowman.net      14379         [ +  - ]:             80 :     if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14380                 :             80 :         ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    14381                 :             80 :                      ARCHIVE_OPTS(.tag = aminfo->dobj.name,
                              14382                 :                :                                   .description = "ACCESS METHOD",
                              14383                 :                :                                   .section = SECTION_PRE_DATA,
                              14384                 :                :                                   .createStmt = q->data,
                              14385                 :                :                                   .dropStmt = delq->data));
                              14386                 :                : 
                              14387                 :                :     /* Dump Access Method Comments */
 3378 sfrost@snowman.net      14388         [ -  + ]:             80 :     if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       14389                 :UBC           0 :         dumpComment(fout, "ACCESS METHOD", qamname,
                              14390                 :                :                     NULL, "",
 3378 sfrost@snowman.net      14391                 :              0 :                     aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
                              14392                 :                : 
 3454 alvherre@alvh.no-ip.    14393                 :CBC          80 :     destroyPQExpBuffer(q);
                              14394                 :             80 :     destroyPQExpBuffer(delq);
 2749 tgl@sss.pgh.pa.us       14395                 :             80 :     free(qamname);
                              14396                 :                : }
                              14397                 :                : 
                              14398                 :                : /*
                              14399                 :                :  * dumpOpclass
                              14400                 :                :  *    write out a single operator class definition
                              14401                 :                :  */
                              14402                 :                : static void
 1669 peter@eisentraut.org    14403                 :            678 : dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
                              14404                 :                : {
 3524 tgl@sss.pgh.pa.us       14405                 :            678 :     DumpOptions *dopt = fout->dopt;
                              14406                 :                :     PQExpBuffer query;
                              14407                 :                :     PQExpBuffer q;
                              14408                 :                :     PQExpBuffer delq;
                              14409                 :                :     PQExpBuffer nameusing;
                              14410                 :                :     PGresult   *res;
                              14411                 :                :     int         ntups;
                              14412                 :                :     int         i_opcintype;
                              14413                 :                :     int         i_opckeytype;
                              14414                 :                :     int         i_opcdefault;
                              14415                 :                :     int         i_opcfamily;
                              14416                 :                :     int         i_opcfamilyname;
                              14417                 :                :     int         i_opcfamilynsp;
                              14418                 :                :     int         i_amname;
                              14419                 :                :     int         i_amopstrategy;
                              14420                 :                :     int         i_amopopr;
                              14421                 :                :     int         i_sortfamily;
                              14422                 :                :     int         i_sortfamilynsp;
                              14423                 :                :     int         i_amprocnum;
                              14424                 :                :     int         i_amproc;
                              14425                 :                :     int         i_amproclefttype;
                              14426                 :                :     int         i_amprocrighttype;
                              14427                 :                :     char       *opcintype;
                              14428                 :                :     char       *opckeytype;
                              14429                 :                :     char       *opcdefault;
                              14430                 :                :     char       *opcfamily;
                              14431                 :                :     char       *opcfamilyname;
                              14432                 :                :     char       *opcfamilynsp;
                              14433                 :                :     char       *amname;
                              14434                 :                :     char       *amopstrategy;
                              14435                 :                :     char       *amopopr;
                              14436                 :                :     char       *sortfamily;
                              14437                 :                :     char       *sortfamilynsp;
                              14438                 :                :     char       *amprocnum;
                              14439                 :                :     char       *amproc;
                              14440                 :                :     char       *amproclefttype;
                              14441                 :                :     char       *amprocrighttype;
                              14442                 :                :     bool        needComma;
                              14443                 :                :     int         i;
                              14444                 :                : 
                              14445                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    14446         [ +  + ]:            678 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       14447                 :             18 :         return;
                              14448                 :                : 
                              14449                 :            660 :     query = createPQExpBuffer();
                              14450                 :            660 :     q = createPQExpBuffer();
                              14451                 :            660 :     delq = createPQExpBuffer();
 2749                         14452                 :            660 :     nameusing = createPQExpBuffer();
                              14453                 :                : 
                              14454                 :                :     /* Get additional fields from the pg_opclass row */
 1362                         14455                 :            660 :     appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                              14456                 :                :                       "opckeytype::pg_catalog.regtype, "
                              14457                 :                :                       "opcdefault, opcfamily, "
                              14458                 :                :                       "opfname AS opcfamilyname, "
                              14459                 :                :                       "nspname AS opcfamilynsp, "
                              14460                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
                              14461                 :                :                       "FROM pg_catalog.pg_opclass c "
                              14462                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
                              14463                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14464                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              14465                 :            660 :                       opcinfo->dobj.catId.oid);
                              14466                 :                : 
 4951 rhaas@postgresql.org    14467                 :            660 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14468                 :                : 
 8439 tgl@sss.pgh.pa.us       14469                 :            660 :     i_opcintype = PQfnumber(res, "opcintype");
                              14470                 :            660 :     i_opckeytype = PQfnumber(res, "opckeytype");
                              14471                 :            660 :     i_opcdefault = PQfnumber(res, "opcdefault");
 6801                         14472                 :            660 :     i_opcfamily = PQfnumber(res, "opcfamily");
 5400                         14473                 :            660 :     i_opcfamilyname = PQfnumber(res, "opcfamilyname");
 6801                         14474                 :            660 :     i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
 8439                         14475                 :            660 :     i_amname = PQfnumber(res, "amname");
                              14476                 :                : 
                              14477                 :                :     /* opcintype may still be needed after we PQclear res */
 3025                         14478                 :            660 :     opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
 8439                         14479                 :            660 :     opckeytype = PQgetvalue(res, 0, i_opckeytype);
                              14480                 :            660 :     opcdefault = PQgetvalue(res, 0, i_opcdefault);
                              14481                 :                :     /* opcfamily will still be needed after we PQclear res */
 5034 bruce@momjian.us        14482                 :            660 :     opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
 5400 tgl@sss.pgh.pa.us       14483                 :            660 :     opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
 6801                         14484                 :            660 :     opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
                              14485                 :                :     /* amname will still be needed after we PQclear res */
 5034 bruce@momjian.us        14486                 :            660 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              14487                 :                : 
 8439 tgl@sss.pgh.pa.us       14488                 :            660 :     appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
 2749                         14489                 :            660 :                       fmtQualifiedDumpable(opcinfo));
 8439                         14490                 :            660 :     appendPQExpBuffer(delq, " USING %s;\n",
                              14491                 :                :                       fmtId(amname));
                              14492                 :                : 
                              14493                 :                :     /* Build the fixed portion of the CREATE command */
 8420 peter_e@gmx.net         14494                 :            660 :     appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
 2749 tgl@sss.pgh.pa.us       14495                 :            660 :                       fmtQualifiedDumpable(opcinfo));
 8439                         14496         [ +  + ]:            660 :     if (strcmp(opcdefault, "t") == 0)
 4310 heikki.linnakangas@i    14497                 :            357 :         appendPQExpBufferStr(q, "DEFAULT ");
 6801 tgl@sss.pgh.pa.us       14498                 :            660 :     appendPQExpBuffer(q, "FOR TYPE %s USING %s",
                              14499                 :                :                       opcintype,
                              14500                 :                :                       fmtId(amname));
 3433                         14501         [ +  - ]:            660 :     if (strlen(opcfamilyname) > 0)
                              14502                 :                :     {
 4310 heikki.linnakangas@i    14503                 :            660 :         appendPQExpBufferStr(q, " FAMILY ");
 2749 tgl@sss.pgh.pa.us       14504                 :            660 :         appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
 3719 heikki.linnakangas@i    14505                 :            660 :         appendPQExpBufferStr(q, fmtId(opcfamilyname));
                              14506                 :                :     }
 4310                         14507                 :            660 :     appendPQExpBufferStr(q, " AS\n    ");
                              14508                 :                : 
 8439 tgl@sss.pgh.pa.us       14509                 :            660 :     needComma = false;
                              14510                 :                : 
                              14511         [ +  + ]:            660 :     if (strcmp(opckeytype, "-") != 0)
                              14512                 :                :     {
 8420 peter_e@gmx.net         14513                 :            252 :         appendPQExpBuffer(q, "STORAGE %s",
                              14514                 :                :                           opckeytype);
 8439 tgl@sss.pgh.pa.us       14515                 :            252 :         needComma = true;
                              14516                 :                :     }
                              14517                 :                : 
                              14518                 :            660 :     PQclear(res);
                              14519                 :                : 
                              14520                 :                :     /*
                              14521                 :                :      * Now fetch and print the OPERATOR entries (pg_amop rows).
                              14522                 :                :      *
                              14523                 :                :      * Print only those opfamily members that are tied to the opclass by
                              14524                 :                :      * pg_depend entries.
                              14525                 :                :      */
                              14526                 :            660 :     resetPQExpBuffer(query);
 1362                         14527                 :            660 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              14528                 :                :                       "amopopr::pg_catalog.regoperator, "
                              14529                 :                :                       "opfname AS sortfamily, "
                              14530                 :                :                       "nspname AS sortfamilynsp "
                              14531                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              14532                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              14533                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              14534                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14535                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              14536                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14537                 :                :                       "AND amopfamily = '%s'::pg_catalog.oid "
                              14538                 :                :                       "ORDER BY amopstrategy",
                              14539                 :            660 :                       opcinfo->dobj.catId.oid,
                              14540                 :                :                       opcfamily);
                              14541                 :                : 
 4960 rhaas@postgresql.org    14542                 :            660 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14543                 :                : 
 8439 tgl@sss.pgh.pa.us       14544                 :            660 :     ntups = PQntuples(res);
                              14545                 :                : 
                              14546                 :            660 :     i_amopstrategy = PQfnumber(res, "amopstrategy");
                              14547                 :            660 :     i_amopopr = PQfnumber(res, "amopopr");
 5400                         14548                 :            660 :     i_sortfamily = PQfnumber(res, "sortfamily");
                              14549                 :            660 :     i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
                              14550                 :                : 
 8439                         14551         [ +  + ]:            898 :     for (i = 0; i < ntups; i++)
                              14552                 :                :     {
                              14553                 :            238 :         amopstrategy = PQgetvalue(res, i, i_amopstrategy);
                              14554                 :            238 :         amopopr = PQgetvalue(res, i, i_amopopr);
 5400                         14555                 :            238 :         sortfamily = PQgetvalue(res, i, i_sortfamily);
                              14556                 :            238 :         sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
                              14557                 :                : 
 8439                         14558         [ +  + ]:            238 :         if (needComma)
 4310 heikki.linnakangas@i    14559                 :            152 :             appendPQExpBufferStr(q, " ,\n    ");
                              14560                 :                : 
 8420 peter_e@gmx.net         14561                 :            238 :         appendPQExpBuffer(q, "OPERATOR %s %s",
                              14562                 :                :                           amopstrategy, amopopr);
                              14563                 :                : 
 5400 tgl@sss.pgh.pa.us       14564         [ -  + ]:            238 :         if (strlen(sortfamily) > 0)
                              14565                 :                :         {
 4310 heikki.linnakangas@i    14566                 :UBC           0 :             appendPQExpBufferStr(q, " FOR ORDER BY ");
 2749 tgl@sss.pgh.pa.us       14567                 :              0 :             appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 4310 heikki.linnakangas@i    14568                 :              0 :             appendPQExpBufferStr(q, fmtId(sortfamily));
                              14569                 :                :         }
                              14570                 :                : 
 8439 tgl@sss.pgh.pa.us       14571                 :CBC         238 :         needComma = true;
                              14572                 :                :     }
                              14573                 :                : 
                              14574                 :            660 :     PQclear(res);
                              14575                 :                : 
                              14576                 :                :     /*
                              14577                 :                :      * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              14578                 :                :      *
                              14579                 :                :      * Print only those opfamily members that are tied to the opclass by
                              14580                 :                :      * pg_depend entries.
                              14581                 :                :      *
                              14582                 :                :      * We print the amproclefttype/amprocrighttype even though in most cases
                              14583                 :                :      * the backend could deduce the right values, because of the corner case
                              14584                 :                :      * of a btree sort support function for a cross-type comparison.
                              14585                 :                :      */
                              14586                 :            660 :     resetPQExpBuffer(query);
                              14587                 :                : 
 1362                         14588                 :            660 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              14589                 :                :                       "amproc::pg_catalog.regprocedure, "
                              14590                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              14591                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              14592                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              14593                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              14594                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14595                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              14596                 :                :                       "AND objid = ap.oid "
                              14597                 :                :                       "ORDER BY amprocnum",
                              14598                 :            660 :                       opcinfo->dobj.catId.oid);
                              14599                 :                : 
 4960 rhaas@postgresql.org    14600                 :            660 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14601                 :                : 
 8439 tgl@sss.pgh.pa.us       14602                 :            660 :     ntups = PQntuples(res);
                              14603                 :                : 
                              14604                 :            660 :     i_amprocnum = PQfnumber(res, "amprocnum");
                              14605                 :            660 :     i_amproc = PQfnumber(res, "amproc");
 5022                         14606                 :            660 :     i_amproclefttype = PQfnumber(res, "amproclefttype");
                              14607                 :            660 :     i_amprocrighttype = PQfnumber(res, "amprocrighttype");
                              14608                 :                : 
 8439                         14609         [ +  + ]:            698 :     for (i = 0; i < ntups; i++)
                              14610                 :                :     {
                              14611                 :             38 :         amprocnum = PQgetvalue(res, i, i_amprocnum);
                              14612                 :             38 :         amproc = PQgetvalue(res, i, i_amproc);
 5022                         14613                 :             38 :         amproclefttype = PQgetvalue(res, i, i_amproclefttype);
                              14614                 :             38 :         amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
                              14615                 :                : 
 8439                         14616         [ +  - ]:             38 :         if (needComma)
 4310 heikki.linnakangas@i    14617                 :             38 :             appendPQExpBufferStr(q, " ,\n    ");
                              14618                 :                : 
 5022 tgl@sss.pgh.pa.us       14619                 :             38 :         appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
                              14620                 :                : 
                              14621   [ +  -  +  - ]:             38 :         if (*amproclefttype && *amprocrighttype)
                              14622                 :             38 :             appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
                              14623                 :                : 
                              14624                 :             38 :         appendPQExpBuffer(q, " %s", amproc);
                              14625                 :                : 
 8439                         14626                 :             38 :         needComma = true;
                              14627                 :                :     }
                              14628                 :                : 
                              14629                 :            660 :     PQclear(res);
                              14630                 :                : 
                              14631                 :                :     /*
                              14632                 :                :      * If needComma is still false it means we haven't added anything after
                              14633                 :                :      * the AS keyword.  To avoid printing broken SQL, append a dummy STORAGE
                              14634                 :                :      * clause with the same datatype.  This isn't sanctioned by the
                              14635                 :                :      * documentation, but actually DefineOpClass will treat it as a no-op.
                              14636                 :                :      */
 3025                         14637         [ +  + ]:            660 :     if (!needComma)
                              14638                 :            322 :         appendPQExpBuffer(q, "STORAGE %s", opcintype);
                              14639                 :                : 
 4310 heikki.linnakangas@i    14640                 :            660 :     appendPQExpBufferStr(q, ";\n");
                              14641                 :                : 
 2749 tgl@sss.pgh.pa.us       14642                 :            660 :     appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
                              14643                 :            660 :     appendPQExpBuffer(nameusing, " USING %s",
                              14644                 :                :                       fmtId(amname));
                              14645                 :                : 
 3980 alvherre@alvh.no-ip.    14646         [ +  + ]:            660 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       14647                 :              6 :         binary_upgrade_extension_member(q, &opcinfo->dobj,
                              14648                 :              6 :                                         "OPERATOR CLASS", nameusing->data,
                              14649                 :              6 :                                         opcinfo->dobj.namespace->dobj.name);
                              14650                 :                : 
 3440 sfrost@snowman.net      14651         [ +  - ]:            660 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14652                 :            660 :         ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    14653                 :            660 :                      ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
                              14654                 :                :                                   .namespace = opcinfo->dobj.namespace->dobj.name,
                              14655                 :                :                                   .owner = opcinfo->rolname,
                              14656                 :                :                                   .description = "OPERATOR CLASS",
                              14657                 :                :                                   .section = SECTION_PRE_DATA,
                              14658                 :                :                                   .createStmt = q->data,
                              14659                 :                :                                   .dropStmt = delq->data));
                              14660                 :                : 
                              14661                 :                :     /* Dump Operator Class Comments */
 3440 sfrost@snowman.net      14662         [ -  + ]:            660 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       14663                 :UBC           0 :         dumpComment(fout, "OPERATOR CLASS", nameusing->data,
 3106                         14664                 :              0 :                     opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
 3440 sfrost@snowman.net      14665                 :              0 :                     opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
                              14666                 :                : 
 3025 tgl@sss.pgh.pa.us       14667                 :CBC         660 :     free(opcintype);
                              14668                 :            660 :     free(opcfamily);
 7960                         14669                 :            660 :     free(amname);
 8439                         14670                 :            660 :     destroyPQExpBuffer(query);
                              14671                 :            660 :     destroyPQExpBuffer(q);
                              14672                 :            660 :     destroyPQExpBuffer(delq);
 2749                         14673                 :            660 :     destroyPQExpBuffer(nameusing);
                              14674                 :                : }
                              14675                 :                : 
                              14676                 :                : /*
                              14677                 :                :  * dumpOpfamily
                              14678                 :                :  *    write out a single operator family definition
                              14679                 :                :  *
                              14680                 :                :  * Note: this also dumps any "loose" operator members that aren't bound to a
                              14681                 :                :  * specific opclass within the opfamily.
                              14682                 :                :  */
                              14683                 :                : static void
 1669 peter@eisentraut.org    14684                 :            561 : dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
                              14685                 :                : {
 3524 tgl@sss.pgh.pa.us       14686                 :            561 :     DumpOptions *dopt = fout->dopt;
                              14687                 :                :     PQExpBuffer query;
                              14688                 :                :     PQExpBuffer q;
                              14689                 :                :     PQExpBuffer delq;
                              14690                 :                :     PQExpBuffer nameusing;
                              14691                 :                :     PGresult   *res;
                              14692                 :                :     PGresult   *res_ops;
                              14693                 :                :     PGresult   *res_procs;
                              14694                 :                :     int         ntups;
                              14695                 :                :     int         i_amname;
                              14696                 :                :     int         i_amopstrategy;
                              14697                 :                :     int         i_amopopr;
                              14698                 :                :     int         i_sortfamily;
                              14699                 :                :     int         i_sortfamilynsp;
                              14700                 :                :     int         i_amprocnum;
                              14701                 :                :     int         i_amproc;
                              14702                 :                :     int         i_amproclefttype;
                              14703                 :                :     int         i_amprocrighttype;
                              14704                 :                :     char       *amname;
                              14705                 :                :     char       *amopstrategy;
                              14706                 :                :     char       *amopopr;
                              14707                 :                :     char       *sortfamily;
                              14708                 :                :     char       *sortfamilynsp;
                              14709                 :                :     char       *amprocnum;
                              14710                 :                :     char       *amproc;
                              14711                 :                :     char       *amproclefttype;
                              14712                 :                :     char       *amprocrighttype;
                              14713                 :                :     bool        needComma;
                              14714                 :                :     int         i;
                              14715                 :                : 
                              14716                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    14717         [ +  + ]:            561 :     if (!dopt->dumpSchema)
 6801 tgl@sss.pgh.pa.us       14718                 :             12 :         return;
                              14719                 :                : 
                              14720                 :            549 :     query = createPQExpBuffer();
                              14721                 :            549 :     q = createPQExpBuffer();
                              14722                 :            549 :     delq = createPQExpBuffer();
 2749                         14723                 :            549 :     nameusing = createPQExpBuffer();
                              14724                 :                : 
                              14725                 :                :     /*
                              14726                 :                :      * Fetch only those opfamily members that are tied directly to the
                              14727                 :                :      * opfamily by pg_depend entries.
                              14728                 :                :      */
 1362                         14729                 :            549 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              14730                 :                :                       "amopopr::pg_catalog.regoperator, "
                              14731                 :                :                       "opfname AS sortfamily, "
                              14732                 :                :                       "nspname AS sortfamilynsp "
                              14733                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              14734                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              14735                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              14736                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              14737                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              14738                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14739                 :                :                       "AND amopfamily = '%u'::pg_catalog.oid "
                              14740                 :                :                       "ORDER BY amopstrategy",
                              14741                 :            549 :                       opfinfo->dobj.catId.oid,
                              14742                 :            549 :                       opfinfo->dobj.catId.oid);
                              14743                 :                : 
 4960 rhaas@postgresql.org    14744                 :            549 :     res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14745                 :                : 
 6801 tgl@sss.pgh.pa.us       14746                 :            549 :     resetPQExpBuffer(query);
                              14747                 :                : 
                              14748                 :            549 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              14749                 :                :                       "amproc::pg_catalog.regprocedure, "
                              14750                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              14751                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              14752                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              14753                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              14754                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              14755                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              14756                 :                :                       "AND objid = ap.oid "
                              14757                 :                :                       "ORDER BY amprocnum",
                              14758                 :            549 :                       opfinfo->dobj.catId.oid);
                              14759                 :                : 
 4960 rhaas@postgresql.org    14760                 :            549 :     res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              14761                 :                : 
                              14762                 :                :     /* Get additional fields from the pg_opfamily row */
 6801 tgl@sss.pgh.pa.us       14763                 :            549 :     resetPQExpBuffer(query);
                              14764                 :                : 
                              14765                 :            549 :     appendPQExpBuffer(query, "SELECT "
                              14766                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
                              14767                 :                :                       "FROM pg_catalog.pg_opfamily "
                              14768                 :                :                       "WHERE oid = '%u'::pg_catalog.oid",
                              14769                 :            549 :                       opfinfo->dobj.catId.oid);
                              14770                 :                : 
 4951 rhaas@postgresql.org    14771                 :            549 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14772                 :                : 
 6801 tgl@sss.pgh.pa.us       14773                 :            549 :     i_amname = PQfnumber(res, "amname");
                              14774                 :                : 
                              14775                 :                :     /* amname will still be needed after we PQclear res */
 5034 bruce@momjian.us        14776                 :            549 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              14777                 :                : 
 6801 tgl@sss.pgh.pa.us       14778                 :            549 :     appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
 2749                         14779                 :            549 :                       fmtQualifiedDumpable(opfinfo));
 6801                         14780                 :            549 :     appendPQExpBuffer(delq, " USING %s;\n",
                              14781                 :                :                       fmtId(amname));
                              14782                 :                : 
                              14783                 :                :     /* Build the fixed portion of the CREATE command */
                              14784                 :            549 :     appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
 2749                         14785                 :            549 :                       fmtQualifiedDumpable(opfinfo));
 6801                         14786                 :            549 :     appendPQExpBuffer(q, " USING %s;\n",
                              14787                 :                :                       fmtId(amname));
                              14788                 :                : 
                              14789                 :            549 :     PQclear(res);
                              14790                 :                : 
                              14791                 :                :     /* Do we need an ALTER to add loose members? */
                              14792   [ +  +  +  + ]:            549 :     if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
                              14793                 :                :     {
                              14794                 :             53 :         appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
 2749                         14795                 :             53 :                           fmtQualifiedDumpable(opfinfo));
 6801                         14796                 :             53 :         appendPQExpBuffer(q, " USING %s ADD\n    ",
                              14797                 :                :                           fmtId(amname));
                              14798                 :                : 
                              14799                 :             53 :         needComma = false;
                              14800                 :                : 
                              14801                 :                :         /*
                              14802                 :                :          * Now fetch and print the OPERATOR entries (pg_amop rows).
                              14803                 :                :          */
                              14804                 :             53 :         ntups = PQntuples(res_ops);
                              14805                 :                : 
                              14806                 :             53 :         i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
                              14807                 :             53 :         i_amopopr = PQfnumber(res_ops, "amopopr");
 5400                         14808                 :             53 :         i_sortfamily = PQfnumber(res_ops, "sortfamily");
                              14809                 :             53 :         i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
                              14810                 :                : 
 6801                         14811         [ +  + ]:            243 :         for (i = 0; i < ntups; i++)
                              14812                 :                :         {
                              14813                 :            190 :             amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
                              14814                 :            190 :             amopopr = PQgetvalue(res_ops, i, i_amopopr);
 5400                         14815                 :            190 :             sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
                              14816                 :            190 :             sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
                              14817                 :                : 
 6801                         14818         [ +  + ]:            190 :             if (needComma)
 4310 heikki.linnakangas@i    14819                 :            152 :                 appendPQExpBufferStr(q, " ,\n    ");
                              14820                 :                : 
 6801 tgl@sss.pgh.pa.us       14821                 :            190 :             appendPQExpBuffer(q, "OPERATOR %s %s",
                              14822                 :                :                               amopstrategy, amopopr);
                              14823                 :                : 
 5400                         14824         [ -  + ]:            190 :             if (strlen(sortfamily) > 0)
                              14825                 :                :             {
 4310 heikki.linnakangas@i    14826                 :UBC           0 :                 appendPQExpBufferStr(q, " FOR ORDER BY ");
 2749 tgl@sss.pgh.pa.us       14827                 :              0 :                 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 4310 heikki.linnakangas@i    14828                 :              0 :                 appendPQExpBufferStr(q, fmtId(sortfamily));
                              14829                 :                :             }
                              14830                 :                : 
 6801 tgl@sss.pgh.pa.us       14831                 :CBC         190 :             needComma = true;
                              14832                 :                :         }
                              14833                 :                : 
                              14834                 :                :         /*
                              14835                 :                :          * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              14836                 :                :          */
                              14837                 :             53 :         ntups = PQntuples(res_procs);
                              14838                 :                : 
                              14839                 :             53 :         i_amprocnum = PQfnumber(res_procs, "amprocnum");
                              14840                 :             53 :         i_amproc = PQfnumber(res_procs, "amproc");
                              14841                 :             53 :         i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
                              14842                 :             53 :         i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
                              14843                 :                : 
                              14844         [ +  + ]:            258 :         for (i = 0; i < ntups; i++)
                              14845                 :                :         {
                              14846                 :            205 :             amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
                              14847                 :            205 :             amproc = PQgetvalue(res_procs, i, i_amproc);
                              14848                 :            205 :             amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
                              14849                 :            205 :             amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
                              14850                 :                : 
                              14851         [ +  + ]:            205 :             if (needComma)
 4310 heikki.linnakangas@i    14852                 :            190 :                 appendPQExpBufferStr(q, " ,\n    ");
                              14853                 :                : 
 6801 tgl@sss.pgh.pa.us       14854                 :            205 :             appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
                              14855                 :                :                               amprocnum, amproclefttype, amprocrighttype,
                              14856                 :                :                               amproc);
                              14857                 :                : 
                              14858                 :            205 :             needComma = true;
                              14859                 :                :         }
                              14860                 :                : 
 4310 heikki.linnakangas@i    14861                 :             53 :         appendPQExpBufferStr(q, ";\n");
                              14862                 :                :     }
                              14863                 :                : 
 2749 tgl@sss.pgh.pa.us       14864                 :            549 :     appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
                              14865                 :            549 :     appendPQExpBuffer(nameusing, " USING %s",
                              14866                 :                :                       fmtId(amname));
                              14867                 :                : 
 3980 alvherre@alvh.no-ip.    14868         [ +  + ]:            549 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       14869                 :              9 :         binary_upgrade_extension_member(q, &opfinfo->dobj,
                              14870                 :              9 :                                         "OPERATOR FAMILY", nameusing->data,
                              14871                 :              9 :                                         opfinfo->dobj.namespace->dobj.name);
                              14872                 :                : 
 3440 sfrost@snowman.net      14873         [ +  - ]:            549 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14874                 :            549 :         ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    14875                 :            549 :                      ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
                              14876                 :                :                                   .namespace = opfinfo->dobj.namespace->dobj.name,
                              14877                 :                :                                   .owner = opfinfo->rolname,
                              14878                 :                :                                   .description = "OPERATOR FAMILY",
                              14879                 :                :                                   .section = SECTION_PRE_DATA,
                              14880                 :                :                                   .createStmt = q->data,
                              14881                 :                :                                   .dropStmt = delq->data));
                              14882                 :                : 
                              14883                 :                :     /* Dump Operator Family Comments */
 3440 sfrost@snowman.net      14884         [ -  + ]:            549 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       14885                 :UBC           0 :         dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
 3106                         14886                 :              0 :                     opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
 3440 sfrost@snowman.net      14887                 :              0 :                     opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
                              14888                 :                : 
 6801 tgl@sss.pgh.pa.us       14889                 :CBC         549 :     free(amname);
                              14890                 :            549 :     PQclear(res_ops);
                              14891                 :            549 :     PQclear(res_procs);
                              14892                 :            549 :     destroyPQExpBuffer(query);
                              14893                 :            549 :     destroyPQExpBuffer(q);
                              14894                 :            549 :     destroyPQExpBuffer(delq);
 2749                         14895                 :            549 :     destroyPQExpBuffer(nameusing);
                              14896                 :                : }
                              14897                 :                : 
                              14898                 :                : /*
                              14899                 :                :  * dumpCollation
                              14900                 :                :  *    write out a single collation definition
                              14901                 :                :  */
                              14902                 :                : static void
 1669 peter@eisentraut.org    14903                 :           4655 : dumpCollation(Archive *fout, const CollInfo *collinfo)
                              14904                 :                : {
 3524 tgl@sss.pgh.pa.us       14905                 :           4655 :     DumpOptions *dopt = fout->dopt;
                              14906                 :                :     PQExpBuffer query;
                              14907                 :                :     PQExpBuffer q;
                              14908                 :                :     PQExpBuffer delq;
                              14909                 :                :     char       *qcollname;
                              14910                 :                :     PGresult   *res;
                              14911                 :                :     int         i_collprovider;
                              14912                 :                :     int         i_collisdeterministic;
                              14913                 :                :     int         i_collcollate;
                              14914                 :                :     int         i_collctype;
                              14915                 :                :     int         i_colllocale;
                              14916                 :                :     int         i_collicurules;
                              14917                 :                :     const char *collprovider;
                              14918                 :                :     const char *collcollate;
                              14919                 :                :     const char *collctype;
                              14920                 :                :     const char *colllocale;
                              14921                 :                :     const char *collicurules;
                              14922                 :                : 
                              14923                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    14924         [ +  + ]:           4655 :     if (!dopt->dumpSchema)
 5320 peter_e@gmx.net         14925                 :             12 :         return;
                              14926                 :                : 
                              14927                 :           4643 :     query = createPQExpBuffer();
                              14928                 :           4643 :     q = createPQExpBuffer();
                              14929                 :           4643 :     delq = createPQExpBuffer();
                              14930                 :                : 
 2749 tgl@sss.pgh.pa.us       14931                 :           4643 :     qcollname = pg_strdup(fmtId(collinfo->dobj.name));
                              14932                 :                : 
                              14933                 :                :     /* Get collation-specific details */
 2256 drowley@postgresql.o    14934                 :           4643 :     appendPQExpBufferStr(query, "SELECT ");
                              14935                 :                : 
 3089 peter_e@gmx.net         14936         [ +  - ]:           4643 :     if (fout->remoteVersion >= 100000)
 2256 drowley@postgresql.o    14937                 :           4643 :         appendPQExpBufferStr(query,
                              14938                 :                :                              "collprovider, "
                              14939                 :                :                              "collversion, ");
                              14940                 :                :     else
 2256 drowley@postgresql.o    14941                 :UBC           0 :         appendPQExpBufferStr(query,
                              14942                 :                :                              "'c' AS collprovider, "
                              14943                 :                :                              "NULL AS collversion, ");
                              14944                 :                : 
 2360 peter@eisentraut.org    14945         [ +  - ]:CBC        4643 :     if (fout->remoteVersion >= 120000)
 2256 drowley@postgresql.o    14946                 :           4643 :         appendPQExpBufferStr(query,
                              14947                 :                :                              "collisdeterministic, ");
                              14948                 :                :     else
 2256 drowley@postgresql.o    14949                 :UBC           0 :         appendPQExpBufferStr(query,
                              14950                 :                :                              "true AS collisdeterministic, ");
                              14951                 :                : 
  546 jdavis@postgresql.or    14952         [ +  - ]:CBC        4643 :     if (fout->remoteVersion >= 170000)
                              14953                 :           4643 :         appendPQExpBufferStr(query,
                              14954                 :                :                              "colllocale, ");
  546 jdavis@postgresql.or    14955         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 150000)
 1109 peter@eisentraut.org    14956                 :              0 :         appendPQExpBufferStr(query,
                              14957                 :                :                              "colliculocale AS colllocale, ");
                              14958                 :                :     else
                              14959                 :              0 :         appendPQExpBufferStr(query,
                              14960                 :                :                              "NULL AS colllocale, ");
                              14961                 :                : 
  913 peter@eisentraut.org    14962         [ +  - ]:CBC        4643 :     if (fout->remoteVersion >= 160000)
                              14963                 :           4643 :         appendPQExpBufferStr(query,
                              14964                 :                :                              "collicurules, ");
                              14965                 :                :     else
  913 peter@eisentraut.org    14966                 :UBC           0 :         appendPQExpBufferStr(query,
                              14967                 :                :                              "NULL AS collicurules, ");
                              14968                 :                : 
 2360 peter@eisentraut.org    14969                 :CBC        4643 :     appendPQExpBuffer(query,
                              14970                 :                :                       "collcollate, "
                              14971                 :                :                       "collctype "
                              14972                 :                :                       "FROM pg_catalog.pg_collation c "
                              14973                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              14974                 :           4643 :                       collinfo->dobj.catId.oid);
                              14975                 :                : 
 4951 rhaas@postgresql.org    14976                 :           4643 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14977                 :                : 
 3089 peter_e@gmx.net         14978                 :           4643 :     i_collprovider = PQfnumber(res, "collprovider");
 2360 peter@eisentraut.org    14979                 :           4643 :     i_collisdeterministic = PQfnumber(res, "collisdeterministic");
 5320 peter_e@gmx.net         14980                 :           4643 :     i_collcollate = PQfnumber(res, "collcollate");
                              14981                 :           4643 :     i_collctype = PQfnumber(res, "collctype");
  546 jdavis@postgresql.or    14982                 :           4643 :     i_colllocale = PQfnumber(res, "colllocale");
  913 peter@eisentraut.org    14983                 :           4643 :     i_collicurules = PQfnumber(res, "collicurules");
                              14984                 :                : 
 3089 peter_e@gmx.net         14985                 :           4643 :     collprovider = PQgetvalue(res, 0, i_collprovider);
                              14986                 :                : 
 1109 peter@eisentraut.org    14987         [ +  + ]:           4643 :     if (!PQgetisnull(res, 0, i_collcollate))
                              14988                 :           2020 :         collcollate = PQgetvalue(res, 0, i_collcollate);
                              14989                 :                :     else
                              14990                 :           2623 :         collcollate = NULL;
                              14991                 :                : 
                              14992         [ +  + ]:           4643 :     if (!PQgetisnull(res, 0, i_collctype))
                              14993                 :           2020 :         collctype = PQgetvalue(res, 0, i_collctype);
                              14994                 :                :     else
                              14995                 :           2623 :         collctype = NULL;
                              14996                 :                : 
                              14997                 :                :     /*
                              14998                 :                :      * Before version 15, collcollate and collctype were of type NAME and
                              14999                 :                :      * non-nullable. Treat empty strings as NULL for consistency.
                              15000                 :                :      */
  746 jdavis@postgresql.or    15001         [ -  + ]:           4643 :     if (fout->remoteVersion < 150000)
                              15002                 :                :     {
  746 jdavis@postgresql.or    15003         [ #  # ]:UBC           0 :         if (collcollate[0] == '\0')
                              15004                 :              0 :             collcollate = NULL;
                              15005         [ #  # ]:              0 :         if (collctype[0] == '\0')
                              15006                 :              0 :             collctype = NULL;
                              15007                 :                :     }
                              15008                 :                : 
  546 jdavis@postgresql.or    15009         [ +  + ]:CBC        4643 :     if (!PQgetisnull(res, 0, i_colllocale))
                              15010                 :           2620 :         colllocale = PQgetvalue(res, 0, i_colllocale);
                              15011                 :                :     else
                              15012                 :           2023 :         colllocale = NULL;
                              15013                 :                : 
  913 peter@eisentraut.org    15014         [ -  + ]:           4643 :     if (!PQgetisnull(res, 0, i_collicurules))
  913 peter@eisentraut.org    15015                 :UBC           0 :         collicurules = PQgetvalue(res, 0, i_collicurules);
                              15016                 :                :     else
  913 peter@eisentraut.org    15017                 :CBC        4643 :         collicurules = NULL;
                              15018                 :                : 
 2749 tgl@sss.pgh.pa.us       15019                 :           4643 :     appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
                              15020                 :           4643 :                       fmtQualifiedDumpable(collinfo));
                              15021                 :                : 
 3089 peter_e@gmx.net         15022                 :           4643 :     appendPQExpBuffer(q, "CREATE COLLATION %s (",
 2749 tgl@sss.pgh.pa.us       15023                 :           4643 :                       fmtQualifiedDumpable(collinfo));
                              15024                 :                : 
 3089 peter_e@gmx.net         15025                 :           4643 :     appendPQExpBufferStr(q, "provider = ");
  542 jdavis@postgresql.or    15026         [ +  + ]:           4643 :     if (collprovider[0] == 'b')
                              15027                 :             19 :         appendPQExpBufferStr(q, "builtin");
                              15028         [ +  + ]:           4624 :     else if (collprovider[0] == 'c')
 3089 peter_e@gmx.net         15029                 :           2020 :         appendPQExpBufferStr(q, "libc");
                              15030         [ +  + ]:           2604 :     else if (collprovider[0] == 'i')
                              15031                 :           2601 :         appendPQExpBufferStr(q, "icu");
 3007                         15032         [ +  - ]:              3 :     else if (collprovider[0] == 'd')
                              15033                 :                :         /* to allow dumping pg_catalog; not accepted on input */
                              15034                 :              3 :         appendPQExpBufferStr(q, "default");
                              15035                 :                :     else
 1247 tgl@sss.pgh.pa.us       15036                 :UBC           0 :         pg_fatal("unrecognized collation provider: %s",
                              15037                 :                :                  collprovider);
                              15038                 :                : 
 2360 peter@eisentraut.org    15039         [ -  + ]:CBC        4643 :     if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
 2360 peter@eisentraut.org    15040                 :UBC           0 :         appendPQExpBufferStr(q, ", deterministic = false");
                              15041                 :                : 
  746 jdavis@postgresql.or    15042         [ +  + ]:CBC        4643 :     if (collprovider[0] == 'd')
                              15043                 :                :     {
  546                         15044   [ +  -  +  -  :              3 :         if (collcollate || collctype || colllocale || collicurules)
                                        +  -  -  + ]
  746 jdavis@postgresql.or    15045                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15046                 :                : 
                              15047                 :                :         /* no locale -- the default collation cannot be reloaded anyway */
                              15048                 :                :     }
  542 jdavis@postgresql.or    15049         [ +  + ]:CBC        4640 :     else if (collprovider[0] == 'b')
                              15050                 :                :     {
                              15051   [ +  -  +  -  :             19 :         if (collcollate || collctype || !colllocale || collicurules)
                                        +  -  -  + ]
  542 jdavis@postgresql.or    15052                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15053                 :                : 
  542 jdavis@postgresql.or    15054                 :CBC          19 :         appendPQExpBufferStr(q, ", locale = ");
                              15055         [ +  - ]:             19 :         appendStringLiteralAH(q, colllocale ? colllocale : "",
                              15056                 :                :                               fout);
                              15057                 :                :     }
  746                         15058         [ +  + ]:           4621 :     else if (collprovider[0] == 'i')
                              15059                 :                :     {
                              15060         [ +  - ]:           2601 :         if (fout->remoteVersion >= 150000)
                              15061                 :                :         {
  546                         15062   [ +  -  +  -  :           2601 :             if (collcollate || collctype || !colllocale)
                                              -  + ]
  746 jdavis@postgresql.or    15063                 :UBC           0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              15064                 :                : 
  746 jdavis@postgresql.or    15065                 :CBC        2601 :             appendPQExpBufferStr(q, ", locale = ");
  546                         15066         [ +  - ]:           2601 :             appendStringLiteralAH(q, colllocale ? colllocale : "",
                              15067                 :                :                                   fout);
                              15068                 :                :         }
                              15069                 :                :         else
                              15070                 :                :         {
  546 jdavis@postgresql.or    15071   [ #  #  #  #  :UBC           0 :             if (!collcollate || !collctype || colllocale ||
                                              #  # ]
  746                         15072         [ #  # ]:              0 :                 strcmp(collcollate, collctype) != 0)
                              15073                 :              0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              15074                 :                : 
 1109 peter@eisentraut.org    15075                 :              0 :             appendPQExpBufferStr(q, ", locale = ");
  746 jdavis@postgresql.or    15076         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              15077                 :                :         }
                              15078                 :                : 
  746 jdavis@postgresql.or    15079         [ -  + ]:CBC        2601 :         if (collicurules)
                              15080                 :                :         {
  746 jdavis@postgresql.or    15081                 :UBC           0 :             appendPQExpBufferStr(q, ", rules = ");
                              15082         [ #  # ]:              0 :             appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
                              15083                 :                :         }
                              15084                 :                :     }
  746 jdavis@postgresql.or    15085         [ +  - ]:CBC        2020 :     else if (collprovider[0] == 'c')
                              15086                 :                :     {
  546                         15087   [ +  -  +  -  :           2020 :         if (colllocale || collicurules || !collcollate || !collctype)
                                        +  -  -  + ]
  746 jdavis@postgresql.or    15088                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              15089                 :                : 
  746 jdavis@postgresql.or    15090   [ +  -  +  -  :CBC        2020 :         if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
                                              +  - ]
                              15091                 :                :         {
                              15092                 :           2020 :             appendPQExpBufferStr(q, ", locale = ");
                              15093         [ +  - ]:           2020 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              15094                 :                :         }
                              15095                 :                :         else
                              15096                 :                :         {
 1109 peter@eisentraut.org    15097                 :UBC           0 :             appendPQExpBufferStr(q, ", lc_collate = ");
  746 jdavis@postgresql.or    15098         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
 1109 peter@eisentraut.org    15099                 :              0 :             appendPQExpBufferStr(q, ", lc_ctype = ");
  746 jdavis@postgresql.or    15100         [ #  # ]:              0 :             appendStringLiteralAH(q, collctype ? collctype : "", fout);
                              15101                 :                :         }
                              15102                 :                :     }
                              15103                 :                :     else
  732 peter@eisentraut.org    15104                 :              0 :         pg_fatal("unrecognized collation provider: %s", collprovider);
                              15105                 :                : 
                              15106                 :                :     /*
                              15107                 :                :      * For binary upgrade, carry over the collation version.  For normal
                              15108                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                              15109                 :                :      */
 1583 tmunro@postgresql.or    15110         [ +  + ]:CBC        4643 :     if (dopt->binary_upgrade)
                              15111                 :                :     {
                              15112                 :                :         int         i_collversion;
                              15113                 :                : 
                              15114                 :              5 :         i_collversion = PQfnumber(res, "collversion");
                              15115         [ +  + ]:              5 :         if (!PQgetisnull(res, 0, i_collversion))
                              15116                 :                :         {
                              15117                 :              4 :             appendPQExpBufferStr(q, ", version = ");
                              15118                 :              4 :             appendStringLiteralAH(q,
                              15119                 :                :                                   PQgetvalue(res, 0, i_collversion),
                              15120                 :                :                                   fout);
                              15121                 :                :         }
                              15122                 :                :     }
                              15123                 :                : 
 4310 heikki.linnakangas@i    15124                 :           4643 :     appendPQExpBufferStr(q, ");\n");
                              15125                 :                : 
 3980 alvherre@alvh.no-ip.    15126         [ +  + ]:           4643 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15127                 :              5 :         binary_upgrade_extension_member(q, &collinfo->dobj,
                              15128                 :                :                                         "COLLATION", qcollname,
                              15129                 :              5 :                                         collinfo->dobj.namespace->dobj.name);
                              15130                 :                : 
 3440 sfrost@snowman.net      15131         [ +  - ]:           4643 :     if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15132                 :           4643 :         ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15133                 :           4643 :                      ARCHIVE_OPTS(.tag = collinfo->dobj.name,
                              15134                 :                :                                   .namespace = collinfo->dobj.namespace->dobj.name,
                              15135                 :                :                                   .owner = collinfo->rolname,
                              15136                 :                :                                   .description = "COLLATION",
                              15137                 :                :                                   .section = SECTION_PRE_DATA,
                              15138                 :                :                                   .createStmt = q->data,
                              15139                 :                :                                   .dropStmt = delq->data));
                              15140                 :                : 
                              15141                 :                :     /* Dump Collation Comments */
 3440 sfrost@snowman.net      15142         [ +  + ]:           4643 :     if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15143                 :           2563 :         dumpComment(fout, "COLLATION", qcollname,
 3440 sfrost@snowman.net      15144                 :           2563 :                     collinfo->dobj.namespace->dobj.name, collinfo->rolname,
                              15145                 :           2563 :                     collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
                              15146                 :                : 
 5320 peter_e@gmx.net         15147                 :           4643 :     PQclear(res);
                              15148                 :                : 
                              15149                 :           4643 :     destroyPQExpBuffer(query);
                              15150                 :           4643 :     destroyPQExpBuffer(q);
                              15151                 :           4643 :     destroyPQExpBuffer(delq);
 2749 tgl@sss.pgh.pa.us       15152                 :           4643 :     free(qcollname);
                              15153                 :                : }
                              15154                 :                : 
                              15155                 :                : /*
                              15156                 :                :  * dumpConversion
                              15157                 :                :  *    write out a single conversion definition
                              15158                 :                :  */
                              15159                 :                : static void
 1669 peter@eisentraut.org    15160                 :            428 : dumpConversion(Archive *fout, const ConvInfo *convinfo)
                              15161                 :                : {
 3524 tgl@sss.pgh.pa.us       15162                 :            428 :     DumpOptions *dopt = fout->dopt;
                              15163                 :                :     PQExpBuffer query;
                              15164                 :                :     PQExpBuffer q;
                              15165                 :                :     PQExpBuffer delq;
                              15166                 :                :     char       *qconvname;
                              15167                 :                :     PGresult   *res;
                              15168                 :                :     int         i_conforencoding;
                              15169                 :                :     int         i_contoencoding;
                              15170                 :                :     int         i_conproc;
                              15171                 :                :     int         i_condefault;
                              15172                 :                :     const char *conforencoding;
                              15173                 :                :     const char *contoencoding;
                              15174                 :                :     const char *conproc;
                              15175                 :                :     bool        condefault;
                              15176                 :                : 
                              15177                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15178         [ +  + ]:            428 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       15179                 :              6 :         return;
                              15180                 :                : 
                              15181                 :            422 :     query = createPQExpBuffer();
                              15182                 :            422 :     q = createPQExpBuffer();
                              15183                 :            422 :     delq = createPQExpBuffer();
                              15184                 :                : 
 2749                         15185                 :            422 :     qconvname = pg_strdup(fmtId(convinfo->dobj.name));
                              15186                 :                : 
                              15187                 :                :     /* Get conversion-specific details */
 5262 peter_e@gmx.net         15188                 :            422 :     appendPQExpBuffer(query, "SELECT "
                              15189                 :                :                       "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
                              15190                 :                :                       "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
                              15191                 :                :                       "conproc, condefault "
                              15192                 :                :                       "FROM pg_catalog.pg_conversion c "
                              15193                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
 7945 tgl@sss.pgh.pa.us       15194                 :            422 :                       convinfo->dobj.catId.oid);
                              15195                 :                : 
 4951 rhaas@postgresql.org    15196                 :            422 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              15197                 :                : 
 7960 tgl@sss.pgh.pa.us       15198                 :            422 :     i_conforencoding = PQfnumber(res, "conforencoding");
                              15199                 :            422 :     i_contoencoding = PQfnumber(res, "contoencoding");
                              15200                 :            422 :     i_conproc = PQfnumber(res, "conproc");
                              15201                 :            422 :     i_condefault = PQfnumber(res, "condefault");
                              15202                 :                : 
                              15203                 :            422 :     conforencoding = PQgetvalue(res, 0, i_conforencoding);
                              15204                 :            422 :     contoencoding = PQgetvalue(res, 0, i_contoencoding);
                              15205                 :            422 :     conproc = PQgetvalue(res, 0, i_conproc);
                              15206                 :            422 :     condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
                              15207                 :                : 
 2749                         15208                 :            422 :     appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
                              15209                 :            422 :                       fmtQualifiedDumpable(convinfo));
                              15210                 :                : 
 7960                         15211         [ +  - ]:            422 :     appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                              15212                 :                :                       (condefault) ? "DEFAULT " : "",
 2749                         15213                 :            422 :                       fmtQualifiedDumpable(convinfo));
 7041                         15214                 :            422 :     appendStringLiteralAH(q, conforencoding, fout);
 4310 heikki.linnakangas@i    15215                 :            422 :     appendPQExpBufferStr(q, " TO ");
 7041 tgl@sss.pgh.pa.us       15216                 :            422 :     appendStringLiteralAH(q, contoencoding, fout);
                              15217                 :                :     /* regproc output is already sufficiently quoted */
 7960                         15218                 :            422 :     appendPQExpBuffer(q, " FROM %s;\n", conproc);
                              15219                 :                : 
 3980 alvherre@alvh.no-ip.    15220         [ +  + ]:            422 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15221                 :              1 :         binary_upgrade_extension_member(q, &convinfo->dobj,
                              15222                 :                :                                         "CONVERSION", qconvname,
                              15223                 :              1 :                                         convinfo->dobj.namespace->dobj.name);
                              15224                 :                : 
 3440 sfrost@snowman.net      15225         [ +  - ]:            422 :     if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15226                 :            422 :         ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15227                 :            422 :                      ARCHIVE_OPTS(.tag = convinfo->dobj.name,
                              15228                 :                :                                   .namespace = convinfo->dobj.namespace->dobj.name,
                              15229                 :                :                                   .owner = convinfo->rolname,
                              15230                 :                :                                   .description = "CONVERSION",
                              15231                 :                :                                   .section = SECTION_PRE_DATA,
                              15232                 :                :                                   .createStmt = q->data,
                              15233                 :                :                                   .dropStmt = delq->data));
                              15234                 :                : 
                              15235                 :                :     /* Dump Conversion Comments */
 3440 sfrost@snowman.net      15236         [ +  - ]:            422 :     if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15237                 :            422 :         dumpComment(fout, "CONVERSION", qconvname,
 3440 sfrost@snowman.net      15238                 :            422 :                     convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                              15239                 :            422 :                     convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
                              15240                 :                : 
 7945 tgl@sss.pgh.pa.us       15241                 :            422 :     PQclear(res);
                              15242                 :                : 
                              15243                 :            422 :     destroyPQExpBuffer(query);
                              15244                 :            422 :     destroyPQExpBuffer(q);
                              15245                 :            422 :     destroyPQExpBuffer(delq);
 2749                         15246                 :            422 :     free(qconvname);
                              15247                 :                : }
                              15248                 :                : 
                              15249                 :                : /*
                              15250                 :                :  * format_aggregate_signature: generate aggregate name and argument list
                              15251                 :                :  *
                              15252                 :                :  * The argument type names are qualified if needed.  The aggregate name
                              15253                 :                :  * is never qualified.
                              15254                 :                :  */
                              15255                 :                : static char *
 1669 peter@eisentraut.org    15256                 :            291 : format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
                              15257                 :                : {
                              15258                 :                :     PQExpBufferData buf;
                              15259                 :                :     int         j;
                              15260                 :                : 
 8511 peter_e@gmx.net         15261                 :            291 :     initPQExpBuffer(&buf);
 8465 bruce@momjian.us        15262         [ -  + ]:            291 :     if (honor_quotes)
 4310 heikki.linnakangas@i    15263                 :UBC           0 :         appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
                              15264                 :                :     else
 4310 heikki.linnakangas@i    15265                 :CBC         291 :         appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
                              15266                 :                : 
 6981 tgl@sss.pgh.pa.us       15267         [ +  + ]:            291 :     if (agginfo->aggfn.nargs == 0)
 2256 drowley@postgresql.o    15268                 :             40 :         appendPQExpBufferStr(&buf, "(*)");
                              15269                 :                :     else
                              15270                 :                :     {
 4310 heikki.linnakangas@i    15271                 :            251 :         appendPQExpBufferChar(&buf, '(');
 6981 tgl@sss.pgh.pa.us       15272         [ +  + ]:            547 :         for (j = 0; j < agginfo->aggfn.nargs; j++)
                              15273         [ +  + ]:            296 :             appendPQExpBuffer(&buf, "%s%s",
                              15274                 :                :                               (j > 0) ? ", " : "",
                              15275                 :                :                               getFormattedTypeName(fout,
 1459                         15276                 :            296 :                                                    agginfo->aggfn.argtypes[j],
                              15277                 :                :                                                    zeroIsError));
 4310 heikki.linnakangas@i    15278                 :            251 :         appendPQExpBufferChar(&buf, ')');
                              15279                 :                :     }
 8511 peter_e@gmx.net         15280                 :            291 :     return buf.data;
                              15281                 :                : }
                              15282                 :                : 
                              15283                 :                : /*
                              15284                 :                :  * dumpAgg
                              15285                 :                :  *    write out a single aggregate definition
                              15286                 :                :  */
                              15287                 :                : static void
 1669 peter@eisentraut.org    15288                 :            298 : dumpAgg(Archive *fout, const AggInfo *agginfo)
                              15289                 :                : {
 3524 tgl@sss.pgh.pa.us       15290                 :            298 :     DumpOptions *dopt = fout->dopt;
                              15291                 :                :     PQExpBuffer query;
                              15292                 :                :     PQExpBuffer q;
                              15293                 :                :     PQExpBuffer delq;
                              15294                 :                :     PQExpBuffer details;
                              15295                 :                :     char       *aggsig;         /* identity signature */
 2999                         15296                 :            298 :     char       *aggfullsig = NULL;  /* full signature */
                              15297                 :                :     char       *aggsig_tag;
                              15298                 :                :     PGresult   *res;
                              15299                 :                :     int         i_agginitval;
                              15300                 :                :     int         i_aggminitval;
                              15301                 :                :     const char *aggtransfn;
                              15302                 :                :     const char *aggfinalfn;
                              15303                 :                :     const char *aggcombinefn;
                              15304                 :                :     const char *aggserialfn;
                              15305                 :                :     const char *aggdeserialfn;
                              15306                 :                :     const char *aggmtransfn;
                              15307                 :                :     const char *aggminvtransfn;
                              15308                 :                :     const char *aggmfinalfn;
                              15309                 :                :     bool        aggfinalextra;
                              15310                 :                :     bool        aggmfinalextra;
                              15311                 :                :     char        aggfinalmodify;
                              15312                 :                :     char        aggmfinalmodify;
                              15313                 :                :     const char *aggsortop;
                              15314                 :                :     char       *aggsortconvop;
                              15315                 :                :     char        aggkind;
                              15316                 :                :     const char *aggtranstype;
                              15317                 :                :     const char *aggtransspace;
                              15318                 :                :     const char *aggmtranstype;
                              15319                 :                :     const char *aggmtransspace;
                              15320                 :                :     const char *agginitval;
                              15321                 :                :     const char *aggminitval;
                              15322                 :                :     const char *proparallel;
                              15323                 :                :     char        defaultfinalmodify;
                              15324                 :                : 
                              15325                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15326         [ +  + ]:            298 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       15327                 :              7 :         return;
                              15328                 :                : 
                              15329                 :            291 :     query = createPQExpBuffer();
                              15330                 :            291 :     q = createPQExpBuffer();
                              15331                 :            291 :     delq = createPQExpBuffer();
                              15332                 :            291 :     details = createPQExpBuffer();
                              15333                 :                : 
 1370                         15334         [ +  + ]:            291 :     if (!fout->is_prepared[PREPQUERY_DUMPAGG])
                              15335                 :                :     {
                              15336                 :                :         /* Set up query for aggregate-specific details */
 1787 drowley@postgresql.o    15337                 :             61 :         appendPQExpBufferStr(query,
                              15338                 :                :                              "PREPARE dumpAgg(pg_catalog.oid) AS\n");
                              15339                 :                : 
                              15340                 :             61 :         appendPQExpBufferStr(query,
                              15341                 :                :                              "SELECT "
                              15342                 :                :                              "aggtransfn,\n"
                              15343                 :                :                              "aggfinalfn,\n"
                              15344                 :                :                              "aggtranstype::pg_catalog.regtype,\n"
                              15345                 :                :                              "agginitval,\n"
                              15346                 :                :                              "aggsortop,\n"
                              15347                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              15348                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
                              15349                 :                : 
 1370 tgl@sss.pgh.pa.us       15350         [ +  - ]:             61 :         if (fout->remoteVersion >= 90400)
                              15351                 :             61 :             appendPQExpBufferStr(query,
                              15352                 :                :                                  "aggkind,\n"
                              15353                 :                :                                  "aggmtransfn,\n"
                              15354                 :                :                                  "aggminvtransfn,\n"
                              15355                 :                :                                  "aggmfinalfn,\n"
                              15356                 :                :                                  "aggmtranstype::pg_catalog.regtype,\n"
                              15357                 :                :                                  "aggfinalextra,\n"
                              15358                 :                :                                  "aggmfinalextra,\n"
                              15359                 :                :                                  "aggtransspace,\n"
                              15360                 :                :                                  "aggmtransspace,\n"
                              15361                 :                :                                  "aggminitval,\n");
                              15362                 :                :         else
 1370 tgl@sss.pgh.pa.us       15363                 :UBC           0 :             appendPQExpBufferStr(query,
                              15364                 :                :                                  "'n' AS aggkind,\n"
                              15365                 :                :                                  "'-' AS aggmtransfn,\n"
                              15366                 :                :                                  "'-' AS aggminvtransfn,\n"
                              15367                 :                :                                  "'-' AS aggmfinalfn,\n"
                              15368                 :                :                                  "0 AS aggmtranstype,\n"
                              15369                 :                :                                  "false AS aggfinalextra,\n"
                              15370                 :                :                                  "false AS aggmfinalextra,\n"
                              15371                 :                :                                  "0 AS aggtransspace,\n"
                              15372                 :                :                                  "0 AS aggmtransspace,\n"
                              15373                 :                :                                  "NULL AS aggminitval,\n");
                              15374                 :                : 
 1370 tgl@sss.pgh.pa.us       15375         [ +  - ]:CBC          61 :         if (fout->remoteVersion >= 90600)
                              15376                 :             61 :             appendPQExpBufferStr(query,
                              15377                 :                :                                  "aggcombinefn,\n"
                              15378                 :                :                                  "aggserialfn,\n"
                              15379                 :                :                                  "aggdeserialfn,\n"
                              15380                 :                :                                  "proparallel,\n");
                              15381                 :                :         else
 1370 tgl@sss.pgh.pa.us       15382                 :UBC           0 :             appendPQExpBufferStr(query,
                              15383                 :                :                                  "'-' AS aggcombinefn,\n"
                              15384                 :                :                                  "'-' AS aggserialfn,\n"
                              15385                 :                :                                  "'-' AS aggdeserialfn,\n"
                              15386                 :                :                                  "'u' AS proparallel,\n");
                              15387                 :                : 
 1370 tgl@sss.pgh.pa.us       15388         [ +  - ]:CBC          61 :         if (fout->remoteVersion >= 110000)
                              15389                 :             61 :             appendPQExpBufferStr(query,
                              15390                 :                :                                  "aggfinalmodify,\n"
                              15391                 :                :                                  "aggmfinalmodify\n");
                              15392                 :                :         else
 1370 tgl@sss.pgh.pa.us       15393                 :UBC           0 :             appendPQExpBufferStr(query,
                              15394                 :                :                                  "'0' AS aggfinalmodify,\n"
                              15395                 :                :                                  "'0' AS aggmfinalmodify\n");
                              15396                 :                : 
 1787 drowley@postgresql.o    15397                 :CBC          61 :         appendPQExpBufferStr(query,
                              15398                 :                :                              "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                              15399                 :                :                              "WHERE a.aggfnoid = p.oid "
                              15400                 :                :                              "AND p.oid = $1");
                              15401                 :                : 
 1370 tgl@sss.pgh.pa.us       15402                 :             61 :         ExecuteSqlStatement(fout, query->data);
                              15403                 :                : 
                              15404                 :             61 :         fout->is_prepared[PREPQUERY_DUMPAGG] = true;
                              15405                 :                :     }
                              15406                 :                : 
                              15407                 :            291 :     printfPQExpBuffer(query,
                              15408                 :                :                       "EXECUTE dumpAgg('%u')",
 1879 peter@eisentraut.org    15409                 :            291 :                       agginfo->aggfn.dobj.catId.oid);
                              15410                 :                : 
 4951 rhaas@postgresql.org    15411                 :            291 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              15412                 :                : 
 8520 tgl@sss.pgh.pa.us       15413                 :            291 :     i_agginitval = PQfnumber(res, "agginitval");
 4165                         15414                 :            291 :     i_aggminitval = PQfnumber(res, "aggminitval");
                              15415                 :                : 
 1879 peter@eisentraut.org    15416                 :            291 :     aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
                              15417                 :            291 :     aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
                              15418                 :            291 :     aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
                              15419                 :            291 :     aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
                              15420                 :            291 :     aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
                              15421                 :            291 :     aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
                              15422                 :            291 :     aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
                              15423                 :            291 :     aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
                              15424                 :            291 :     aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
                              15425                 :            291 :     aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
                              15426                 :            291 :     aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
                              15427                 :            291 :     aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
                              15428                 :            291 :     aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
                              15429                 :            291 :     aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
                              15430                 :            291 :     aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
                              15431                 :            291 :     aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
                              15432                 :            291 :     aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
                              15433                 :            291 :     aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
 8520 tgl@sss.pgh.pa.us       15434                 :            291 :     agginitval = PQgetvalue(res, 0, i_agginitval);
 4165                         15435                 :            291 :     aggminitval = PQgetvalue(res, 0, i_aggminitval);
 1879 peter@eisentraut.org    15436                 :            291 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
                              15437                 :                : 
                              15438                 :                :     {
                              15439                 :                :         char       *funcargs;
                              15440                 :                :         char       *funciargs;
                              15441                 :                : 
 4386 tgl@sss.pgh.pa.us       15442                 :            291 :         funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              15443                 :            291 :         funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              15444                 :            291 :         aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
                              15445                 :            291 :         aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
                              15446                 :                :     }
                              15447                 :                : 
 7945                         15448                 :            291 :     aggsig_tag = format_aggregate_signature(agginfo, fout, false);
                              15449                 :                : 
                              15450                 :                :     /* identify default modify flag for aggkind (must match DefineAggregate) */
 2884                         15451         [ +  + ]:            291 :     defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
                              15452                 :                :     /* replace omitted flags for old versions */
                              15453         [ -  + ]:            291 :     if (aggfinalmodify == '0')
 2884 tgl@sss.pgh.pa.us       15454                 :UBC           0 :         aggfinalmodify = defaultfinalmodify;
 2884 tgl@sss.pgh.pa.us       15455         [ -  + ]:CBC         291 :     if (aggmfinalmodify == '0')
 2884 tgl@sss.pgh.pa.us       15456                 :UBC           0 :         aggmfinalmodify = defaultfinalmodify;
                              15457                 :                : 
                              15458                 :                :     /* regproc and regtype output is already sufficiently quoted */
 3251 tgl@sss.pgh.pa.us       15459                 :CBC         291 :     appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                              15460                 :                :                       aggtransfn, aggtranstype);
                              15461                 :                : 
 4312                         15462         [ +  + ]:            291 :     if (strcmp(aggtransspace, "0") != 0)
                              15463                 :                :     {
                              15464                 :              5 :         appendPQExpBuffer(details, ",\n    SSPACE = %s",
                              15465                 :                :                           aggtransspace);
                              15466                 :                :     }
                              15467                 :                : 
 8520                         15468         [ +  + ]:            291 :     if (!PQgetisnull(res, 0, i_agginitval))
                              15469                 :                :     {
 4310 heikki.linnakangas@i    15470                 :            213 :         appendPQExpBufferStr(details, ",\n    INITCOND = ");
 7041 tgl@sss.pgh.pa.us       15471                 :            213 :         appendStringLiteralAH(details, agginitval, fout);
                              15472                 :                :     }
                              15473                 :                : 
 8520                         15474         [ +  + ]:            291 :     if (strcmp(aggfinalfn, "-") != 0)
                              15475                 :                :     {
 8420 peter_e@gmx.net         15476                 :            138 :         appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                              15477                 :                :                           aggfinalfn);
 4154 tgl@sss.pgh.pa.us       15478         [ +  + ]:            138 :         if (aggfinalextra)
                              15479                 :             10 :             appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
 2884                         15480         [ +  + ]:            138 :         if (aggfinalmodify != defaultfinalmodify)
                              15481                 :                :         {
                              15482   [ -  +  -  - ]:             38 :             switch (aggfinalmodify)
                              15483                 :                :             {
 2884 tgl@sss.pgh.pa.us       15484                 :UBC           0 :                 case AGGMODIFY_READ_ONLY:
                              15485                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_ONLY");
                              15486                 :              0 :                     break;
 2665 tgl@sss.pgh.pa.us       15487                 :CBC          38 :                 case AGGMODIFY_SHAREABLE:
                              15488                 :             38 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = SHAREABLE");
 2884                         15489                 :             38 :                     break;
 2884 tgl@sss.pgh.pa.us       15490                 :UBC           0 :                 case AGGMODIFY_READ_WRITE:
                              15491                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_WRITE");
                              15492                 :              0 :                     break;
                              15493                 :              0 :                 default:
 1247                         15494                 :              0 :                     pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
                              15495                 :                :                              agginfo->aggfn.dobj.name);
                              15496                 :                :                     break;
                              15497                 :                :             }
                              15498                 :                :         }
                              15499                 :                :     }
                              15500                 :                : 
 3517 rhaas@postgresql.org    15501         [ -  + ]:CBC         291 :     if (strcmp(aggcombinefn, "-") != 0)
 3376 rhaas@postgresql.org    15502                 :UBC           0 :         appendPQExpBuffer(details, ",\n    COMBINEFUNC = %s", aggcombinefn);
                              15503                 :                : 
 3448 rhaas@postgresql.org    15504         [ -  + ]:CBC         291 :     if (strcmp(aggserialfn, "-") != 0)
 3376 rhaas@postgresql.org    15505                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SERIALFUNC = %s", aggserialfn);
                              15506                 :                : 
 3363 tgl@sss.pgh.pa.us       15507         [ -  + ]:CBC         291 :     if (strcmp(aggdeserialfn, "-") != 0)
 3376 rhaas@postgresql.org    15508                 :UBC           0 :         appendPQExpBuffer(details, ",\n    DESERIALFUNC = %s", aggdeserialfn);
                              15509                 :                : 
 4165 tgl@sss.pgh.pa.us       15510         [ +  + ]:CBC         291 :     if (strcmp(aggmtransfn, "-") != 0)
                              15511                 :                :     {
                              15512                 :             30 :         appendPQExpBuffer(details, ",\n    MSFUNC = %s,\n    MINVFUNC = %s,\n    MSTYPE = %s",
                              15513                 :                :                           aggmtransfn,
                              15514                 :                :                           aggminvtransfn,
                              15515                 :                :                           aggmtranstype);
                              15516                 :                :     }
                              15517                 :                : 
                              15518         [ -  + ]:            291 :     if (strcmp(aggmtransspace, "0") != 0)
                              15519                 :                :     {
 4165 tgl@sss.pgh.pa.us       15520                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MSSPACE = %s",
                              15521                 :                :                           aggmtransspace);
                              15522                 :                :     }
                              15523                 :                : 
 4165 tgl@sss.pgh.pa.us       15524         [ +  + ]:CBC         291 :     if (!PQgetisnull(res, 0, i_aggminitval))
                              15525                 :                :     {
                              15526                 :             10 :         appendPQExpBufferStr(details, ",\n    MINITCOND = ");
                              15527                 :             10 :         appendStringLiteralAH(details, aggminitval, fout);
                              15528                 :                :     }
                              15529                 :                : 
                              15530         [ -  + ]:            291 :     if (strcmp(aggmfinalfn, "-") != 0)
                              15531                 :                :     {
 4165 tgl@sss.pgh.pa.us       15532                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MFINALFUNC = %s",
                              15533                 :                :                           aggmfinalfn);
 4154                         15534         [ #  # ]:              0 :         if (aggmfinalextra)
                              15535                 :              0 :             appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
 2884                         15536         [ #  # ]:              0 :         if (aggmfinalmodify != defaultfinalmodify)
                              15537                 :                :         {
                              15538   [ #  #  #  # ]:              0 :             switch (aggmfinalmodify)
                              15539                 :                :             {
                              15540                 :              0 :                 case AGGMODIFY_READ_ONLY:
                              15541                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_ONLY");
                              15542                 :              0 :                     break;
 2665                         15543                 :              0 :                 case AGGMODIFY_SHAREABLE:
                              15544                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = SHAREABLE");
 2884                         15545                 :              0 :                     break;
                              15546                 :              0 :                 case AGGMODIFY_READ_WRITE:
                              15547                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_WRITE");
                              15548                 :              0 :                     break;
                              15549                 :              0 :                 default:
 1247                         15550                 :              0 :                     pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
                              15551                 :                :                              agginfo->aggfn.dobj.name);
                              15552                 :                :                     break;
                              15553                 :                :             }
                              15554                 :                :         }
                              15555                 :                :     }
                              15556                 :                : 
 1838 peter@eisentraut.org    15557                 :CBC         291 :     aggsortconvop = getFormattedOperatorName(aggsortop);
 4207 sfrost@snowman.net      15558         [ -  + ]:            291 :     if (aggsortconvop)
                              15559                 :                :     {
 7452 tgl@sss.pgh.pa.us       15560                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SORTOP = %s",
                              15561                 :                :                           aggsortconvop);
 4207 sfrost@snowman.net      15562                 :              0 :         free(aggsortconvop);
                              15563                 :                :     }
                              15564                 :                : 
 2884 tgl@sss.pgh.pa.us       15565         [ +  + ]:CBC         291 :     if (aggkind == AGGKIND_HYPOTHETICAL)
 4275                         15566                 :              5 :         appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
                              15567                 :                : 
 1879 peter@eisentraut.org    15568         [ +  + ]:            291 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              15569                 :                :     {
 3426 rhaas@postgresql.org    15570         [ +  - ]:              5 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              15571                 :              5 :             appendPQExpBufferStr(details, ",\n    PARALLEL = safe");
 3426 rhaas@postgresql.org    15572         [ #  # ]:UBC           0 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              15573                 :              0 :             appendPQExpBufferStr(details, ",\n    PARALLEL = restricted");
                              15574         [ #  # ]:              0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
 1247 tgl@sss.pgh.pa.us       15575                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              15576                 :                :                      agginfo->aggfn.dobj.name);
                              15577                 :                :     }
                              15578                 :                : 
 8502 tgl@sss.pgh.pa.us       15579                 :CBC         291 :     appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
 7857                         15580                 :            291 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              15581                 :                :                       aggsig);
                              15582                 :                : 
 2749                         15583         [ +  - ]:            582 :     appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
                              15584                 :            291 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              15585                 :                :                       aggfullsig ? aggfullsig : aggsig, details->data);
                              15586                 :                : 
 3980 alvherre@alvh.no-ip.    15587         [ +  + ]:            291 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15588                 :             49 :         binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
                              15589                 :                :                                         "AGGREGATE", aggsig,
                              15590                 :             49 :                                         agginfo->aggfn.dobj.namespace->dobj.name);
                              15591                 :                : 
 3440 sfrost@snowman.net      15592         [ +  + ]:            291 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15593                 :            274 :         ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
                              15594                 :            274 :                      agginfo->aggfn.dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15595                 :            274 :                      ARCHIVE_OPTS(.tag = aggsig_tag,
                              15596                 :                :                                   .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
                              15597                 :                :                                   .owner = agginfo->aggfn.rolname,
                              15598                 :                :                                   .description = "AGGREGATE",
                              15599                 :                :                                   .section = SECTION_PRE_DATA,
                              15600                 :                :                                   .createStmt = q->data,
                              15601                 :                :                                   .dropStmt = delq->data));
                              15602                 :                : 
                              15603                 :                :     /* Dump Aggregate Comments */
 3440 sfrost@snowman.net      15604         [ +  + ]:            291 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15605                 :             10 :         dumpComment(fout, "AGGREGATE", aggsig,
 3440 sfrost@snowman.net      15606                 :             10 :                     agginfo->aggfn.dobj.namespace->dobj.name,
                              15607                 :             10 :                     agginfo->aggfn.rolname,
                              15608                 :             10 :                     agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              15609                 :                : 
                              15610         [ -  + ]:            291 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       15611                 :UBC           0 :         dumpSecLabel(fout, "AGGREGATE", aggsig,
 3440 sfrost@snowman.net      15612                 :              0 :                      agginfo->aggfn.dobj.namespace->dobj.name,
                              15613                 :              0 :                      agginfo->aggfn.rolname,
 2999 tgl@sss.pgh.pa.us       15614                 :              0 :                      agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              15615                 :                : 
                              15616                 :                :     /*
                              15617                 :                :      * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
                              15618                 :                :      * command look like a function's GRANT; in particular this affects the
                              15619                 :                :      * syntax for zero-argument aggregates and ordered-set aggregates.
                              15620                 :                :      */
 7945 tgl@sss.pgh.pa.us       15621                 :CBC         291 :     free(aggsig);
                              15622                 :                : 
 4961 rhaas@postgresql.org    15623                 :            291 :     aggsig = format_function_signature(fout, &agginfo->aggfn, true);
                              15624                 :                : 
 3440 sfrost@snowman.net      15625         [ +  + ]:            291 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       15626                 :             18 :         dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
                              15627                 :                :                 "FUNCTION", aggsig, NULL,
 3440 sfrost@snowman.net      15628                 :             18 :                 agginfo->aggfn.dobj.namespace->dobj.name,
  523 tgl@sss.pgh.pa.us       15629                 :             18 :                 NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
                              15630                 :                : 
 7945                         15631                 :            291 :     free(aggsig);
 1178 peter@eisentraut.org    15632                 :            291 :     free(aggfullsig);
 7945 tgl@sss.pgh.pa.us       15633                 :            291 :     free(aggsig_tag);
                              15634                 :                : 
 8520                         15635                 :            291 :     PQclear(res);
                              15636                 :                : 
                              15637                 :            291 :     destroyPQExpBuffer(query);
 8800                         15638                 :            291 :     destroyPQExpBuffer(q);
                              15639                 :            291 :     destroyPQExpBuffer(delq);
                              15640                 :            291 :     destroyPQExpBuffer(details);
                              15641                 :                : }
                              15642                 :                : 
                              15643                 :                : /*
                              15644                 :                :  * dumpTSParser
                              15645                 :                :  *    write out a single text search parser
                              15646                 :                :  */
                              15647                 :                : static void
 1669 peter@eisentraut.org    15648                 :             47 : dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
                              15649                 :                : {
 3524 tgl@sss.pgh.pa.us       15650                 :             47 :     DumpOptions *dopt = fout->dopt;
                              15651                 :                :     PQExpBuffer q;
                              15652                 :                :     PQExpBuffer delq;
                              15653                 :                :     char       *qprsname;
                              15654                 :                : 
                              15655                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15656         [ +  + ]:             47 :     if (!dopt->dumpSchema)
 6591 tgl@sss.pgh.pa.us       15657                 :              6 :         return;
                              15658                 :                : 
                              15659                 :             41 :     q = createPQExpBuffer();
                              15660                 :             41 :     delq = createPQExpBuffer();
                              15661                 :                : 
 2749                         15662                 :             41 :     qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
                              15663                 :                : 
 6591                         15664                 :             41 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
 2749                         15665                 :             41 :                       fmtQualifiedDumpable(prsinfo));
                              15666                 :                : 
 6591                         15667                 :             41 :     appendPQExpBuffer(q, "    START = %s,\n",
 4960 rhaas@postgresql.org    15668                 :             41 :                       convertTSFunction(fout, prsinfo->prsstart));
 6591 tgl@sss.pgh.pa.us       15669                 :             41 :     appendPQExpBuffer(q, "    GETTOKEN = %s,\n",
 4960 rhaas@postgresql.org    15670                 :             41 :                       convertTSFunction(fout, prsinfo->prstoken));
 6591 tgl@sss.pgh.pa.us       15671                 :             41 :     appendPQExpBuffer(q, "    END = %s,\n",
 4960 rhaas@postgresql.org    15672                 :             41 :                       convertTSFunction(fout, prsinfo->prsend));
 6591 tgl@sss.pgh.pa.us       15673         [ +  + ]:             41 :     if (prsinfo->prsheadline != InvalidOid)
                              15674                 :              3 :         appendPQExpBuffer(q, "    HEADLINE = %s,\n",
 4960 rhaas@postgresql.org    15675                 :              3 :                           convertTSFunction(fout, prsinfo->prsheadline));
 6591 tgl@sss.pgh.pa.us       15676                 :             41 :     appendPQExpBuffer(q, "    LEXTYPES = %s );\n",
 4960 rhaas@postgresql.org    15677                 :             41 :                       convertTSFunction(fout, prsinfo->prslextype));
                              15678                 :                : 
 2749 tgl@sss.pgh.pa.us       15679                 :             41 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
                              15680                 :             41 :                       fmtQualifiedDumpable(prsinfo));
                              15681                 :                : 
 3980 alvherre@alvh.no-ip.    15682         [ +  + ]:             41 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15683                 :              1 :         binary_upgrade_extension_member(q, &prsinfo->dobj,
                              15684                 :                :                                         "TEXT SEARCH PARSER", qprsname,
                              15685                 :              1 :                                         prsinfo->dobj.namespace->dobj.name);
                              15686                 :                : 
 3440 sfrost@snowman.net      15687         [ +  - ]:             41 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15688                 :             41 :         ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15689                 :             41 :                      ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
                              15690                 :                :                                   .namespace = prsinfo->dobj.namespace->dobj.name,
                              15691                 :                :                                   .description = "TEXT SEARCH PARSER",
                              15692                 :                :                                   .section = SECTION_PRE_DATA,
                              15693                 :                :                                   .createStmt = q->data,
                              15694                 :                :                                   .dropStmt = delq->data));
                              15695                 :                : 
                              15696                 :                :     /* Dump Parser Comments */
 3440 sfrost@snowman.net      15697         [ +  - ]:             41 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15698                 :             41 :         dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
 3106                         15699                 :             41 :                     prsinfo->dobj.namespace->dobj.name, "",
 3440 sfrost@snowman.net      15700                 :             41 :                     prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
                              15701                 :                : 
 6591 tgl@sss.pgh.pa.us       15702                 :             41 :     destroyPQExpBuffer(q);
                              15703                 :             41 :     destroyPQExpBuffer(delq);
 2749                         15704                 :             41 :     free(qprsname);
                              15705                 :                : }
                              15706                 :                : 
                              15707                 :                : /*
                              15708                 :                :  * dumpTSDictionary
                              15709                 :                :  *    write out a single text search dictionary
                              15710                 :                :  */
                              15711                 :                : static void
 1669 peter@eisentraut.org    15712                 :            179 : dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
                              15713                 :                : {
 3524 tgl@sss.pgh.pa.us       15714                 :            179 :     DumpOptions *dopt = fout->dopt;
                              15715                 :                :     PQExpBuffer q;
                              15716                 :                :     PQExpBuffer delq;
                              15717                 :                :     PQExpBuffer query;
                              15718                 :                :     char       *qdictname;
                              15719                 :                :     PGresult   *res;
                              15720                 :                :     char       *nspname;
                              15721                 :                :     char       *tmplname;
                              15722                 :                : 
                              15723                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15724         [ +  + ]:            179 :     if (!dopt->dumpSchema)
 6591 tgl@sss.pgh.pa.us       15725                 :              6 :         return;
                              15726                 :                : 
                              15727                 :            173 :     q = createPQExpBuffer();
                              15728                 :            173 :     delq = createPQExpBuffer();
                              15729                 :            173 :     query = createPQExpBuffer();
                              15730                 :                : 
 2749                         15731                 :            173 :     qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
                              15732                 :                : 
                              15733                 :                :     /* Fetch name and namespace of the dictionary's template */
 6591                         15734                 :            173 :     appendPQExpBuffer(query, "SELECT nspname, tmplname "
                              15735                 :                :                       "FROM pg_ts_template p, pg_namespace n "
                              15736                 :                :                       "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
                              15737                 :            173 :                       dictinfo->dicttemplate);
 4951 rhaas@postgresql.org    15738                 :            173 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6591 tgl@sss.pgh.pa.us       15739                 :            173 :     nspname = PQgetvalue(res, 0, 0);
                              15740                 :            173 :     tmplname = PQgetvalue(res, 0, 1);
                              15741                 :                : 
                              15742                 :            173 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
 2749                         15743                 :            173 :                       fmtQualifiedDumpable(dictinfo));
                              15744                 :                : 
 4310 heikki.linnakangas@i    15745                 :            173 :     appendPQExpBufferStr(q, "    TEMPLATE = ");
 2749 tgl@sss.pgh.pa.us       15746                 :            173 :     appendPQExpBuffer(q, "%s.", fmtId(nspname));
 4310 heikki.linnakangas@i    15747                 :            173 :     appendPQExpBufferStr(q, fmtId(tmplname));
                              15748                 :                : 
 6591 tgl@sss.pgh.pa.us       15749                 :            173 :     PQclear(res);
                              15750                 :                : 
                              15751                 :                :     /* the dictinitoption can be dumped straight into the command */
                              15752         [ +  + ]:            173 :     if (dictinfo->dictinitoption)
 6590                         15753                 :            132 :         appendPQExpBuffer(q, ",\n    %s", dictinfo->dictinitoption);
                              15754                 :                : 
 4310 heikki.linnakangas@i    15755                 :            173 :     appendPQExpBufferStr(q, " );\n");
                              15756                 :                : 
 2749 tgl@sss.pgh.pa.us       15757                 :            173 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
                              15758                 :            173 :                       fmtQualifiedDumpable(dictinfo));
                              15759                 :                : 
 3980 alvherre@alvh.no-ip.    15760         [ +  + ]:            173 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15761                 :             10 :         binary_upgrade_extension_member(q, &dictinfo->dobj,
                              15762                 :                :                                         "TEXT SEARCH DICTIONARY", qdictname,
                              15763                 :             10 :                                         dictinfo->dobj.namespace->dobj.name);
                              15764                 :                : 
 3440 sfrost@snowman.net      15765         [ +  - ]:            173 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15766                 :            173 :         ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15767                 :            173 :                      ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
                              15768                 :                :                                   .namespace = dictinfo->dobj.namespace->dobj.name,
                              15769                 :                :                                   .owner = dictinfo->rolname,
                              15770                 :                :                                   .description = "TEXT SEARCH DICTIONARY",
                              15771                 :                :                                   .section = SECTION_PRE_DATA,
                              15772                 :                :                                   .createStmt = q->data,
                              15773                 :                :                                   .dropStmt = delq->data));
                              15774                 :                : 
                              15775                 :                :     /* Dump Dictionary Comments */
 3440 sfrost@snowman.net      15776         [ +  + ]:            173 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15777                 :            128 :         dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
 3106                         15778                 :            128 :                     dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
 3440 sfrost@snowman.net      15779                 :            128 :                     dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
                              15780                 :                : 
 6591 tgl@sss.pgh.pa.us       15781                 :            173 :     destroyPQExpBuffer(q);
                              15782                 :            173 :     destroyPQExpBuffer(delq);
                              15783                 :            173 :     destroyPQExpBuffer(query);
 2749                         15784                 :            173 :     free(qdictname);
                              15785                 :                : }
                              15786                 :                : 
                              15787                 :                : /*
                              15788                 :                :  * dumpTSTemplate
                              15789                 :                :  *    write out a single text search template
                              15790                 :                :  */
                              15791                 :                : static void
 1669 peter@eisentraut.org    15792                 :             59 : dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
                              15793                 :                : {
 3524 tgl@sss.pgh.pa.us       15794                 :             59 :     DumpOptions *dopt = fout->dopt;
                              15795                 :                :     PQExpBuffer q;
                              15796                 :                :     PQExpBuffer delq;
                              15797                 :                :     char       *qtmplname;
                              15798                 :                : 
                              15799                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15800         [ +  + ]:             59 :     if (!dopt->dumpSchema)
 6591 tgl@sss.pgh.pa.us       15801                 :              6 :         return;
                              15802                 :                : 
                              15803                 :             53 :     q = createPQExpBuffer();
                              15804                 :             53 :     delq = createPQExpBuffer();
                              15805                 :                : 
 2749                         15806                 :             53 :     qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
                              15807                 :                : 
 6591                         15808                 :             53 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
 2749                         15809                 :             53 :                       fmtQualifiedDumpable(tmplinfo));
                              15810                 :                : 
 6591                         15811         [ +  + ]:             53 :     if (tmplinfo->tmplinit != InvalidOid)
                              15812                 :             15 :         appendPQExpBuffer(q, "    INIT = %s,\n",
 4960 rhaas@postgresql.org    15813                 :             15 :                           convertTSFunction(fout, tmplinfo->tmplinit));
 6591 tgl@sss.pgh.pa.us       15814                 :             53 :     appendPQExpBuffer(q, "    LEXIZE = %s );\n",
 4960 rhaas@postgresql.org    15815                 :             53 :                       convertTSFunction(fout, tmplinfo->tmpllexize));
                              15816                 :                : 
 2749 tgl@sss.pgh.pa.us       15817                 :             53 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
                              15818                 :             53 :                       fmtQualifiedDumpable(tmplinfo));
                              15819                 :                : 
 3980 alvherre@alvh.no-ip.    15820         [ +  + ]:             53 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15821                 :              1 :         binary_upgrade_extension_member(q, &tmplinfo->dobj,
                              15822                 :                :                                         "TEXT SEARCH TEMPLATE", qtmplname,
                              15823                 :              1 :                                         tmplinfo->dobj.namespace->dobj.name);
                              15824                 :                : 
 3440 sfrost@snowman.net      15825         [ +  - ]:             53 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15826                 :             53 :         ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15827                 :             53 :                      ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
                              15828                 :                :                                   .namespace = tmplinfo->dobj.namespace->dobj.name,
                              15829                 :                :                                   .description = "TEXT SEARCH TEMPLATE",
                              15830                 :                :                                   .section = SECTION_PRE_DATA,
                              15831                 :                :                                   .createStmt = q->data,
                              15832                 :                :                                   .dropStmt = delq->data));
                              15833                 :                : 
                              15834                 :                :     /* Dump Template Comments */
 3440 sfrost@snowman.net      15835         [ +  - ]:             53 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15836                 :             53 :         dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
 3106                         15837                 :             53 :                     tmplinfo->dobj.namespace->dobj.name, "",
 3440 sfrost@snowman.net      15838                 :             53 :                     tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
                              15839                 :                : 
 6591 tgl@sss.pgh.pa.us       15840                 :             53 :     destroyPQExpBuffer(q);
                              15841                 :             53 :     destroyPQExpBuffer(delq);
 2749                         15842                 :             53 :     free(qtmplname);
                              15843                 :                : }
                              15844                 :                : 
                              15845                 :                : /*
                              15846                 :                :  * dumpTSConfig
                              15847                 :                :  *    write out a single text search configuration
                              15848                 :                :  */
                              15849                 :                : static void
 1669 peter@eisentraut.org    15850                 :            154 : dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
                              15851                 :                : {
 3524 tgl@sss.pgh.pa.us       15852                 :            154 :     DumpOptions *dopt = fout->dopt;
                              15853                 :                :     PQExpBuffer q;
                              15854                 :                :     PQExpBuffer delq;
                              15855                 :                :     PQExpBuffer query;
                              15856                 :                :     char       *qcfgname;
                              15857                 :                :     PGresult   *res;
                              15858                 :                :     char       *nspname;
                              15859                 :                :     char       *prsname;
                              15860                 :                :     int         ntups,
                              15861                 :                :                 i;
                              15862                 :                :     int         i_tokenname;
                              15863                 :                :     int         i_dictname;
                              15864                 :                : 
                              15865                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15866         [ +  + ]:            154 :     if (!dopt->dumpSchema)
 6591 tgl@sss.pgh.pa.us       15867                 :              6 :         return;
                              15868                 :                : 
                              15869                 :            148 :     q = createPQExpBuffer();
                              15870                 :            148 :     delq = createPQExpBuffer();
                              15871                 :            148 :     query = createPQExpBuffer();
                              15872                 :                : 
 2749                         15873                 :            148 :     qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
                              15874                 :                : 
                              15875                 :                :     /* Fetch name and namespace of the config's parser */
 6591                         15876                 :            148 :     appendPQExpBuffer(query, "SELECT nspname, prsname "
                              15877                 :                :                       "FROM pg_ts_parser p, pg_namespace n "
                              15878                 :                :                       "WHERE p.oid = '%u' AND n.oid = prsnamespace",
                              15879                 :            148 :                       cfginfo->cfgparser);
 4951 rhaas@postgresql.org    15880                 :            148 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6591 tgl@sss.pgh.pa.us       15881                 :            148 :     nspname = PQgetvalue(res, 0, 0);
                              15882                 :            148 :     prsname = PQgetvalue(res, 0, 1);
                              15883                 :                : 
                              15884                 :            148 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
 2749                         15885                 :            148 :                       fmtQualifiedDumpable(cfginfo));
                              15886                 :                : 
                              15887                 :            148 :     appendPQExpBuffer(q, "    PARSER = %s.", fmtId(nspname));
 6591                         15888                 :            148 :     appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
                              15889                 :                : 
                              15890                 :            148 :     PQclear(res);
                              15891                 :                : 
                              15892                 :            148 :     resetPQExpBuffer(query);
                              15893                 :            148 :     appendPQExpBuffer(query,
                              15894                 :                :                       "SELECT\n"
                              15895                 :                :                       "  ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
                              15896                 :                :                       "    WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
                              15897                 :                :                       "  m.mapdict::pg_catalog.regdictionary AS dictname\n"
                              15898                 :                :                       "FROM pg_catalog.pg_ts_config_map AS m\n"
                              15899                 :                :                       "WHERE m.mapcfg = '%u'\n"
                              15900                 :                :                       "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
                              15901                 :            148 :                       cfginfo->cfgparser, cfginfo->dobj.catId.oid);
                              15902                 :                : 
 4960 rhaas@postgresql.org    15903                 :            148 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 6591 tgl@sss.pgh.pa.us       15904                 :            148 :     ntups = PQntuples(res);
                              15905                 :                : 
                              15906                 :            148 :     i_tokenname = PQfnumber(res, "tokenname");
                              15907                 :            148 :     i_dictname = PQfnumber(res, "dictname");
                              15908                 :                : 
                              15909         [ +  + ]:           3095 :     for (i = 0; i < ntups; i++)
                              15910                 :                :     {
 6505 bruce@momjian.us        15911                 :           2947 :         char       *tokenname = PQgetvalue(res, i, i_tokenname);
                              15912                 :           2947 :         char       *dictname = PQgetvalue(res, i, i_dictname);
                              15913                 :                : 
 6591 tgl@sss.pgh.pa.us       15914         [ +  + ]:           2947 :         if (i == 0 ||
 6505 bruce@momjian.us        15915         [ +  + ]:           2799 :             strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
                              15916                 :                :         {
                              15917                 :                :             /* starting a new token type, so start a new command */
 6591 tgl@sss.pgh.pa.us       15918         [ +  + ]:           2812 :             if (i > 0)
 4310 heikki.linnakangas@i    15919                 :           2664 :                 appendPQExpBufferStr(q, ";\n");
 6591 tgl@sss.pgh.pa.us       15920                 :           2812 :             appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
 2749                         15921                 :           2812 :                               fmtQualifiedDumpable(cfginfo));
                              15922                 :                :             /* tokenname needs quoting, dictname does NOT */
 6591                         15923                 :           2812 :             appendPQExpBuffer(q, "    ADD MAPPING FOR %s WITH %s",
                              15924                 :                :                               fmtId(tokenname), dictname);
                              15925                 :                :         }
                              15926                 :                :         else
                              15927                 :            135 :             appendPQExpBuffer(q, ", %s", dictname);
                              15928                 :                :     }
                              15929                 :                : 
                              15930         [ +  - ]:            148 :     if (ntups > 0)
 4310 heikki.linnakangas@i    15931                 :            148 :         appendPQExpBufferStr(q, ";\n");
                              15932                 :                : 
 6591 tgl@sss.pgh.pa.us       15933                 :            148 :     PQclear(res);
                              15934                 :                : 
 2749                         15935                 :            148 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
                              15936                 :            148 :                       fmtQualifiedDumpable(cfginfo));
                              15937                 :                : 
 3980 alvherre@alvh.no-ip.    15938         [ +  + ]:            148 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       15939                 :              5 :         binary_upgrade_extension_member(q, &cfginfo->dobj,
                              15940                 :                :                                         "TEXT SEARCH CONFIGURATION", qcfgname,
                              15941                 :              5 :                                         cfginfo->dobj.namespace->dobj.name);
                              15942                 :                : 
 3440 sfrost@snowman.net      15943         [ +  - ]:            148 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15944                 :            148 :         ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    15945                 :            148 :                      ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
                              15946                 :                :                                   .namespace = cfginfo->dobj.namespace->dobj.name,
                              15947                 :                :                                   .owner = cfginfo->rolname,
                              15948                 :                :                                   .description = "TEXT SEARCH CONFIGURATION",
                              15949                 :                :                                   .section = SECTION_PRE_DATA,
                              15950                 :                :                                   .createStmt = q->data,
                              15951                 :                :                                   .dropStmt = delq->data));
                              15952                 :                : 
                              15953                 :                :     /* Dump Configuration Comments */
 3440 sfrost@snowman.net      15954         [ +  + ]:            148 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       15955                 :            128 :         dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
 3106                         15956                 :            128 :                     cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
 3440 sfrost@snowman.net      15957                 :            128 :                     cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
                              15958                 :                : 
 6591 tgl@sss.pgh.pa.us       15959                 :            148 :     destroyPQExpBuffer(q);
                              15960                 :            148 :     destroyPQExpBuffer(delq);
                              15961                 :            148 :     destroyPQExpBuffer(query);
 2749                         15962                 :            148 :     free(qcfgname);
                              15963                 :                : }
                              15964                 :                : 
                              15965                 :                : /*
                              15966                 :                :  * dumpForeignDataWrapper
                              15967                 :                :  *    write out a single foreign-data wrapper definition
                              15968                 :                :  */
                              15969                 :                : static void
 1669 peter@eisentraut.org    15970                 :             58 : dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
                              15971                 :                : {
 3524 tgl@sss.pgh.pa.us       15972                 :             58 :     DumpOptions *dopt = fout->dopt;
                              15973                 :                :     PQExpBuffer q;
                              15974                 :                :     PQExpBuffer delq;
                              15975                 :                :     char       *qfdwname;
                              15976                 :                : 
                              15977                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    15978         [ +  + ]:             58 :     if (!dopt->dumpSchema)
 6105 peter_e@gmx.net         15979                 :              7 :         return;
                              15980                 :                : 
                              15981                 :             51 :     q = createPQExpBuffer();
                              15982                 :             51 :     delq = createPQExpBuffer();
                              15983                 :                : 
 5034 bruce@momjian.us        15984                 :             51 :     qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
                              15985                 :                : 
 6038 peter_e@gmx.net         15986                 :             51 :     appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
                              15987                 :                :                       qfdwname);
                              15988                 :                : 
 5313 tgl@sss.pgh.pa.us       15989         [ -  + ]:             51 :     if (strcmp(fdwinfo->fdwhandler, "-") != 0)
 5313 tgl@sss.pgh.pa.us       15990                 :UBC           0 :         appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
                              15991                 :                : 
 5313 tgl@sss.pgh.pa.us       15992         [ -  + ]:CBC          51 :     if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
 5313 tgl@sss.pgh.pa.us       15993                 :UBC           0 :         appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
                              15994                 :                : 
 5313 tgl@sss.pgh.pa.us       15995         [ -  + ]:CBC          51 :     if (strlen(fdwinfo->fdwoptions) > 0)
 4993 peter_e@gmx.net         15996                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", fdwinfo->fdwoptions);
                              15997                 :                : 
 4310 heikki.linnakangas@i    15998                 :CBC          51 :     appendPQExpBufferStr(q, ";\n");
                              15999                 :                : 
 6105 peter_e@gmx.net         16000                 :             51 :     appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                              16001                 :                :                       qfdwname);
                              16002                 :                : 
 3980 alvherre@alvh.no-ip.    16003         [ +  + ]:             51 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       16004                 :              2 :         binary_upgrade_extension_member(q, &fdwinfo->dobj,
                              16005                 :                :                                         "FOREIGN DATA WRAPPER", qfdwname,
                              16006                 :                :                                         NULL);
                              16007                 :                : 
 3440 sfrost@snowman.net      16008         [ +  - ]:             51 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16009                 :             51 :         ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    16010                 :             51 :                      ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
                              16011                 :                :                                   .owner = fdwinfo->rolname,
                              16012                 :                :                                   .description = "FOREIGN DATA WRAPPER",
                              16013                 :                :                                   .section = SECTION_PRE_DATA,
                              16014                 :                :                                   .createStmt = q->data,
                              16015                 :                :                                   .dropStmt = delq->data));
                              16016                 :                : 
                              16017                 :                :     /* Dump Foreign Data Wrapper Comments */
 2784 tgl@sss.pgh.pa.us       16018         [ -  + ]:             51 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       16019                 :UBC           0 :         dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
 2784                         16020                 :              0 :                     NULL, fdwinfo->rolname,
                              16021                 :              0 :                     fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
                              16022                 :                : 
                              16023                 :                :     /* Handle the ACL */
 3440 sfrost@snowman.net      16024         [ +  + ]:CBC          51 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       16025                 :             37 :         dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
                              16026                 :                :                 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
 1370                         16027                 :             37 :                 NULL, fdwinfo->rolname, &fdwinfo->dacl);
                              16028                 :                : 
 5323                         16029                 :             51 :     free(qfdwname);
                              16030                 :                : 
 6105 peter_e@gmx.net         16031                 :             51 :     destroyPQExpBuffer(q);
                              16032                 :             51 :     destroyPQExpBuffer(delq);
                              16033                 :                : }
                              16034                 :                : 
                              16035                 :                : /*
                              16036                 :                :  * dumpForeignServer
                              16037                 :                :  *    write out a foreign server definition
                              16038                 :                :  */
                              16039                 :                : static void
 1669 peter@eisentraut.org    16040                 :             62 : dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
                              16041                 :                : {
 3524 tgl@sss.pgh.pa.us       16042                 :             62 :     DumpOptions *dopt = fout->dopt;
                              16043                 :                :     PQExpBuffer q;
                              16044                 :                :     PQExpBuffer delq;
                              16045                 :                :     PQExpBuffer query;
                              16046                 :                :     PGresult   *res;
                              16047                 :                :     char       *qsrvname;
                              16048                 :                :     char       *fdwname;
                              16049                 :                : 
                              16050                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    16051         [ +  + ]:             62 :     if (!dopt->dumpSchema)
 6105 peter_e@gmx.net         16052                 :              9 :         return;
                              16053                 :                : 
                              16054                 :             53 :     q = createPQExpBuffer();
                              16055                 :             53 :     delq = createPQExpBuffer();
                              16056                 :             53 :     query = createPQExpBuffer();
                              16057                 :                : 
 5034 bruce@momjian.us        16058                 :             53 :     qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
                              16059                 :                : 
                              16060                 :                :     /* look up the foreign-data wrapper */
 6105 peter_e@gmx.net         16061                 :             53 :     appendPQExpBuffer(query, "SELECT fdwname "
                              16062                 :                :                       "FROM pg_foreign_data_wrapper w "
                              16063                 :                :                       "WHERE w.oid = '%u'",
                              16064                 :             53 :                       srvinfo->srvfdw);
 4951 rhaas@postgresql.org    16065                 :             53 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6105 peter_e@gmx.net         16066                 :             53 :     fdwname = PQgetvalue(res, 0, 0);
                              16067                 :                : 
 5323 tgl@sss.pgh.pa.us       16068                 :             53 :     appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
 6105 peter_e@gmx.net         16069   [ +  -  -  + ]:             53 :     if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
                              16070                 :                :     {
 4310 heikki.linnakangas@i    16071                 :UBC           0 :         appendPQExpBufferStr(q, " TYPE ");
 5995                         16072                 :              0 :         appendStringLiteralAH(q, srvinfo->srvtype, fout);
                              16073                 :                :     }
 6105 peter_e@gmx.net         16074   [ +  -  -  + ]:CBC          53 :     if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
                              16075                 :                :     {
 4310 heikki.linnakangas@i    16076                 :UBC           0 :         appendPQExpBufferStr(q, " VERSION ");
 5995                         16077                 :              0 :         appendStringLiteralAH(q, srvinfo->srvversion, fout);
                              16078                 :                :     }
                              16079                 :                : 
 4310 heikki.linnakangas@i    16080                 :CBC          53 :     appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
                              16081                 :             53 :     appendPQExpBufferStr(q, fmtId(fdwname));
                              16082                 :                : 
 6105 peter_e@gmx.net         16083   [ +  -  -  + ]:             53 :     if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
 4993 peter_e@gmx.net         16084                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", srvinfo->srvoptions);
                              16085                 :                : 
 4310 heikki.linnakangas@i    16086                 :CBC          53 :     appendPQExpBufferStr(q, ";\n");
                              16087                 :                : 
 6105 peter_e@gmx.net         16088                 :             53 :     appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                              16089                 :                :                       qsrvname);
                              16090                 :                : 
 3980 alvherre@alvh.no-ip.    16091         [ +  + ]:             53 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       16092                 :              2 :         binary_upgrade_extension_member(q, &srvinfo->dobj,
                              16093                 :                :                                         "SERVER", qsrvname, NULL);
                              16094                 :                : 
 3440 sfrost@snowman.net      16095         [ +  - ]:             53 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16096                 :             53 :         ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    16097                 :             53 :                      ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
                              16098                 :                :                                   .owner = srvinfo->rolname,
                              16099                 :                :                                   .description = "SERVER",
                              16100                 :                :                                   .section = SECTION_PRE_DATA,
                              16101                 :                :                                   .createStmt = q->data,
                              16102                 :                :                                   .dropStmt = delq->data));
                              16103                 :                : 
                              16104                 :                :     /* Dump Foreign Server Comments */
 2784 tgl@sss.pgh.pa.us       16105         [ -  + ]:             53 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       16106                 :UBC           0 :         dumpComment(fout, "SERVER", qsrvname,
 2784                         16107                 :              0 :                     NULL, srvinfo->rolname,
                              16108                 :              0 :                     srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
                              16109                 :                : 
                              16110                 :                :     /* Handle the ACL */
 3440 sfrost@snowman.net      16111         [ +  + ]:CBC          53 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1883 tgl@sss.pgh.pa.us       16112                 :             37 :         dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
                              16113                 :                :                 "FOREIGN SERVER", qsrvname, NULL, NULL,
 1370                         16114                 :             37 :                 NULL, srvinfo->rolname, &srvinfo->dacl);
                              16115                 :                : 
                              16116                 :                :     /* Dump user mappings */
 3440 sfrost@snowman.net      16117         [ +  - ]:             53 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
                              16118                 :             53 :         dumpUserMappings(fout,
                              16119                 :             53 :                          srvinfo->dobj.name, NULL,
                              16120                 :             53 :                          srvinfo->rolname,
                              16121                 :             53 :                          srvinfo->dobj.catId, srvinfo->dobj.dumpId);
                              16122                 :                : 
 1413 tgl@sss.pgh.pa.us       16123                 :             53 :     PQclear(res);
                              16124                 :                : 
 5323                         16125                 :             53 :     free(qsrvname);
                              16126                 :                : 
 6105 peter_e@gmx.net         16127                 :             53 :     destroyPQExpBuffer(q);
                              16128                 :             53 :     destroyPQExpBuffer(delq);
 3435 tgl@sss.pgh.pa.us       16129                 :             53 :     destroyPQExpBuffer(query);
                              16130                 :                : }
                              16131                 :                : 
                              16132                 :                : /*
                              16133                 :                :  * dumpUserMappings
                              16134                 :                :  *
                              16135                 :                :  * This routine is used to dump any user mappings associated with the
                              16136                 :                :  * server handed to this routine. Should be called after ArchiveEntry()
                              16137                 :                :  * for the server.
                              16138                 :                :  */
                              16139                 :                : static void
 5533                         16140                 :             53 : dumpUserMappings(Archive *fout,
                              16141                 :                :                  const char *servername, const char *namespace,
                              16142                 :                :                  const char *owner,
                              16143                 :                :                  CatalogId catalogId, DumpId dumpId)
                              16144                 :                : {
                              16145                 :                :     PQExpBuffer q;
                              16146                 :                :     PQExpBuffer delq;
                              16147                 :                :     PQExpBuffer query;
                              16148                 :                :     PQExpBuffer tag;
                              16149                 :                :     PGresult   *res;
                              16150                 :                :     int         ntups;
                              16151                 :                :     int         i_usename;
                              16152                 :                :     int         i_umoptions;
                              16153                 :                :     int         i;
                              16154                 :                : 
 6105 peter_e@gmx.net         16155                 :             53 :     q = createPQExpBuffer();
                              16156                 :             53 :     tag = createPQExpBuffer();
                              16157                 :             53 :     delq = createPQExpBuffer();
                              16158                 :             53 :     query = createPQExpBuffer();
                              16159                 :                : 
                              16160                 :                :     /*
                              16161                 :                :      * We read from the publicly accessible view pg_user_mappings, so as not
                              16162                 :                :      * to fail if run by a non-superuser.  Note that the view will show
                              16163                 :                :      * umoptions as null if the user hasn't got privileges for the associated
                              16164                 :                :      * server; this means that pg_dump will dump such a mapping, but with no
                              16165                 :                :      * OPTIONS clause.  A possible alternative is to skip such mappings
                              16166                 :                :      * altogether, but it's not clear that that's an improvement.
                              16167                 :                :      */
                              16168                 :             53 :     appendPQExpBuffer(query,
                              16169                 :                :                       "SELECT usename, "
                              16170                 :                :                       "array_to_string(ARRAY("
                              16171                 :                :                       "SELECT quote_ident(option_name) || ' ' || "
                              16172                 :                :                       "quote_literal(option_value) "
                              16173                 :                :                       "FROM pg_options_to_table(umoptions) "
                              16174                 :                :                       "ORDER BY option_name"
                              16175                 :                :                       "), E',\n    ') AS umoptions "
                              16176                 :                :                       "FROM pg_user_mappings "
                              16177                 :                :                       "WHERE srvid = '%u' "
                              16178                 :                :                       "ORDER BY usename",
                              16179                 :                :                       catalogId.oid);
                              16180                 :                : 
 4960 rhaas@postgresql.org    16181                 :             53 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16182                 :                : 
 6105 peter_e@gmx.net         16183                 :             53 :     ntups = PQntuples(res);
 5533 tgl@sss.pgh.pa.us       16184                 :             53 :     i_usename = PQfnumber(res, "usename");
 6105 peter_e@gmx.net         16185                 :             53 :     i_umoptions = PQfnumber(res, "umoptions");
                              16186                 :                : 
                              16187         [ +  + ]:             90 :     for (i = 0; i < ntups; i++)
                              16188                 :                :     {
                              16189                 :                :         char       *usename;
                              16190                 :                :         char       *umoptions;
                              16191                 :                : 
 5533 tgl@sss.pgh.pa.us       16192                 :             37 :         usename = PQgetvalue(res, i, i_usename);
 6105 peter_e@gmx.net         16193                 :             37 :         umoptions = PQgetvalue(res, i, i_umoptions);
                              16194                 :                : 
                              16195                 :             37 :         resetPQExpBuffer(q);
 5533 tgl@sss.pgh.pa.us       16196                 :             37 :         appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
 6105 peter_e@gmx.net         16197                 :             37 :         appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
                              16198                 :                : 
                              16199   [ +  -  -  + ]:             37 :         if (umoptions && strlen(umoptions) > 0)
 4993 peter_e@gmx.net         16200                 :UBC           0 :             appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", umoptions);
                              16201                 :                : 
 4310 heikki.linnakangas@i    16202                 :CBC          37 :         appendPQExpBufferStr(q, ";\n");
                              16203                 :                : 
 6105 peter_e@gmx.net         16204                 :             37 :         resetPQExpBuffer(delq);
 5533 tgl@sss.pgh.pa.us       16205                 :             37 :         appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
                              16206                 :             37 :         appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
                              16207                 :                : 
 6105 peter_e@gmx.net         16208                 :             37 :         resetPQExpBuffer(tag);
 5533 tgl@sss.pgh.pa.us       16209                 :             37 :         appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
                              16210                 :                :                           usename, servername);
                              16211                 :                : 
 6105 peter_e@gmx.net         16212                 :             37 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    16213                 :             37 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16214                 :                :                                   .namespace = namespace,
                              16215                 :                :                                   .owner = owner,
                              16216                 :                :                                   .description = "USER MAPPING",
                              16217                 :                :                                   .section = SECTION_PRE_DATA,
                              16218                 :                :                                   .createStmt = q->data,
                              16219                 :                :                                   .dropStmt = delq->data));
                              16220                 :                :     }
                              16221                 :                : 
 6105 peter_e@gmx.net         16222                 :             53 :     PQclear(res);
                              16223                 :                : 
                              16224                 :             53 :     destroyPQExpBuffer(query);
                              16225                 :             53 :     destroyPQExpBuffer(delq);
 4207 sfrost@snowman.net      16226                 :             53 :     destroyPQExpBuffer(tag);
 6105 peter_e@gmx.net         16227                 :             53 :     destroyPQExpBuffer(q);
                              16228                 :             53 : }
                              16229                 :                : 
                              16230                 :                : /*
                              16231                 :                :  * Write out default privileges information
                              16232                 :                :  */
                              16233                 :                : static void
 1669 peter@eisentraut.org    16234                 :            184 : dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
                              16235                 :                : {
 3524 tgl@sss.pgh.pa.us       16236                 :            184 :     DumpOptions *dopt = fout->dopt;
                              16237                 :                :     PQExpBuffer q;
                              16238                 :                :     PQExpBuffer tag;
                              16239                 :                :     const char *type;
                              16240                 :                : 
                              16241                 :                :     /* Do nothing if not dumping schema, or if we're skipping ACLs */
  285 nathan@postgresql.or    16242   [ +  +  +  + ]:            184 :     if (!dopt->dumpSchema || dopt->aclsSkip)
 5815 tgl@sss.pgh.pa.us       16243                 :             28 :         return;
                              16244                 :                : 
                              16245                 :            156 :     q = createPQExpBuffer();
                              16246                 :            156 :     tag = createPQExpBuffer();
                              16247                 :                : 
                              16248   [ +  -  +  +  :            156 :     switch (daclinfo->defaclobjtype)
                                           -  -  - ]
                              16249                 :                :     {
                              16250                 :             73 :         case DEFACLOBJ_RELATION:
 5808                         16251                 :             73 :             type = "TABLES";
 5815                         16252                 :             73 :             break;
 5815 tgl@sss.pgh.pa.us       16253                 :UBC           0 :         case DEFACLOBJ_SEQUENCE:
 5808                         16254                 :              0 :             type = "SEQUENCES";
 5815                         16255                 :              0 :             break;
 5815 tgl@sss.pgh.pa.us       16256                 :CBC          73 :         case DEFACLOBJ_FUNCTION:
 5808                         16257                 :             73 :             type = "FUNCTIONS";
 5815                         16258                 :             73 :             break;
 4654                         16259                 :             10 :         case DEFACLOBJ_TYPE:
                              16260                 :             10 :             type = "TYPES";
                              16261                 :             10 :             break;
 3084 teodor@sigaev.ru        16262                 :UBC           0 :         case DEFACLOBJ_NAMESPACE:
                              16263                 :              0 :             type = "SCHEMAS";
                              16264                 :              0 :             break;
  155 fujii@postgresql.org    16265                 :              0 :         case DEFACLOBJ_LARGEOBJECT:
                              16266                 :              0 :             type = "LARGE OBJECTS";
                              16267                 :              0 :             break;
 5815 tgl@sss.pgh.pa.us       16268                 :              0 :         default:
                              16269                 :                :             /* shouldn't get here */
 1247                         16270                 :              0 :             pg_fatal("unrecognized object type in default privileges: %d",
                              16271                 :                :                      (int) daclinfo->defaclobjtype);
                              16272                 :                :             type = "";            /* keep compiler quiet */
                              16273                 :                :     }
                              16274                 :                : 
 5808 tgl@sss.pgh.pa.us       16275                 :CBC         156 :     appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
                              16276                 :                : 
                              16277                 :                :     /* build the actual command(s) for this tuple */
 5815                         16278         [ -  + ]:            156 :     if (!buildDefaultACLCommands(type,
                              16279                 :            156 :                                  daclinfo->dobj.namespace != NULL ?
                              16280                 :             74 :                                  daclinfo->dobj.namespace->dobj.name : NULL,
 1370                         16281                 :            156 :                                  daclinfo->dacl.acl,
                              16282                 :            156 :                                  daclinfo->dacl.acldefault,
 5815                         16283         [ +  + ]:            156 :                                  daclinfo->defaclrole,
                              16284                 :                :                                  fout->remoteVersion,
                              16285                 :                :                                  q))
 1247 tgl@sss.pgh.pa.us       16286                 :UBC           0 :         pg_fatal("could not parse default ACL list (%s)",
                              16287                 :                :                  daclinfo->dacl.acl);
                              16288                 :                : 
 3440 sfrost@snowman.net      16289         [ +  - ]:CBC         156 :     if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              16290                 :            156 :         ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    16291         [ +  + ]:            156 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16292                 :                :                                   .namespace = daclinfo->dobj.namespace ?
                              16293                 :                :                                   daclinfo->dobj.namespace->dobj.name : NULL,
                              16294                 :                :                                   .owner = daclinfo->defaclrole,
                              16295                 :                :                                   .description = "DEFAULT ACL",
                              16296                 :                :                                   .section = SECTION_POST_DATA,
                              16297                 :                :                                   .createStmt = q->data));
                              16298                 :                : 
 5815 tgl@sss.pgh.pa.us       16299                 :            156 :     destroyPQExpBuffer(tag);
                              16300                 :            156 :     destroyPQExpBuffer(q);
                              16301                 :                : }
                              16302                 :                : 
                              16303                 :                : /*----------
                              16304                 :                :  * Write out grant/revoke information
                              16305                 :                :  *
                              16306                 :                :  * 'objDumpId' is the dump ID of the underlying object.
                              16307                 :                :  * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
                              16308                 :                :  *      or InvalidDumpId if there is no need for a second dependency.
                              16309                 :                :  * 'type' must be one of
                              16310                 :                :  *      TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
                              16311                 :                :  *      FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
                              16312                 :                :  * 'name' is the formatted name of the object.  Must be quoted etc. already.
                              16313                 :                :  * 'subname' is the formatted name of the sub-object, if any.  Must be quoted.
                              16314                 :                :  *      (Currently we assume that subname is only provided for table columns.)
                              16315                 :                :  * 'nspname' is the namespace the object is in (NULL if none).
                              16316                 :                :  * 'tag' is the tag to use for the ACL TOC entry; typically, this is NULL
                              16317                 :                :  *      to use the default for the object type.
                              16318                 :                :  * 'owner' is the owner, NULL if there is no owner (for languages).
                              16319                 :                :  * 'dacl' is the DumpableAcl struct for the object.
                              16320                 :                :  *
                              16321                 :                :  * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
                              16322                 :                :  * no ACL entry was created.
                              16323                 :                :  *----------
                              16324                 :                :  */
                              16325                 :                : static DumpId
 1883                         16326                 :          28647 : dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
                              16327                 :                :         const char *type, const char *name, const char *subname,
                              16328                 :                :         const char *nspname, const char *tag, const char *owner,
                              16329                 :                :         const DumpableAcl *dacl)
                              16330                 :                : {
                              16331                 :          28647 :     DumpId      aclDumpId = InvalidDumpId;
 3524                         16332                 :          28647 :     DumpOptions *dopt = fout->dopt;
 1370                         16333                 :          28647 :     const char *acls = dacl->acl;
                              16334                 :          28647 :     const char *acldefault = dacl->acldefault;
                              16335                 :          28647 :     char        privtype = dacl->privtype;
                              16336                 :          28647 :     const char *initprivs = dacl->initprivs;
                              16337                 :                :     const char *baseacls;
                              16338                 :                :     PQExpBuffer sql;
                              16339                 :                : 
                              16340                 :                :     /* Do nothing if ACL dump is not enabled */
 3980 alvherre@alvh.no-ip.    16341         [ +  + ]:          28647 :     if (dopt->aclsSkip)
 1883 tgl@sss.pgh.pa.us       16342                 :            324 :         return InvalidDumpId;
                              16343                 :                : 
                              16344                 :                :     /* --data-only skips ACLs *except* large object ACLs */
  285 nathan@postgresql.or    16345   [ +  +  -  + ]:          28323 :     if (!dopt->dumpSchema && strcmp(type, "LARGE OBJECT") != 0)
 1883 tgl@sss.pgh.pa.us       16346                 :UBC           0 :         return InvalidDumpId;
                              16347                 :                : 
 8524 tgl@sss.pgh.pa.us       16348                 :CBC       28323 :     sql = createPQExpBuffer();
                              16349                 :                : 
                              16350                 :                :     /*
                              16351                 :                :      * In binary upgrade mode, we don't run an extension's script but instead
                              16352                 :                :      * dump out the objects independently and then recreate them.  To preserve
                              16353                 :                :      * any initial privileges which were set on extension objects, we need to
                              16354                 :                :      * compute the set of GRANT and REVOKE commands necessary to get from the
                              16355                 :                :      * default privileges of an object to its initial privileges as recorded
                              16356                 :                :      * in pg_init_privs.
                              16357                 :                :      *
                              16358                 :                :      * At restore time, we apply these commands after having called
                              16359                 :                :      * binary_upgrade_set_record_init_privs(true).  That tells the backend to
                              16360                 :                :      * copy the results into pg_init_privs.  This is how we preserve the
                              16361                 :                :      * contents of that catalog across binary upgrades.
                              16362                 :                :      */
 1370                         16363   [ +  +  +  +  :          28323 :     if (dopt->binary_upgrade && privtype == 'e' &&
                                              +  - ]
                              16364         [ +  - ]:             13 :         initprivs && *initprivs != '\0')
                              16365                 :                :     {
 2256 drowley@postgresql.o    16366                 :             13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
 2749 tgl@sss.pgh.pa.us       16367         [ -  + ]:             13 :         if (!buildACLCommands(name, subname, nspname, type,
                              16368                 :                :                               initprivs, acldefault, owner,
                              16369                 :                :                               "", fout->remoteVersion, sql))
 1247 tgl@sss.pgh.pa.us       16370                 :UBC           0 :             pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              16371                 :                :                      initprivs, acldefault, name, type);
 2256 drowley@postgresql.o    16372                 :CBC          13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
                              16373                 :                :     }
                              16374                 :                : 
                              16375                 :                :     /*
                              16376                 :                :      * Now figure the GRANT and REVOKE commands needed to get to the object's
                              16377                 :                :      * actual current ACL, starting from the initprivs if given, else from the
                              16378                 :                :      * object-type-specific default.  Also, while buildACLCommands will assume
                              16379                 :                :      * that a NULL/empty acls string means it needn't do anything, what that
                              16380                 :                :      * actually represents is the object-type-specific default; so we need to
                              16381                 :                :      * substitute the acldefault string to get the right results in that case.
                              16382                 :                :      */
 1370 tgl@sss.pgh.pa.us       16383   [ +  +  +  + ]:          28323 :     if (initprivs && *initprivs != '\0')
                              16384                 :                :     {
                              16385                 :          26304 :         baseacls = initprivs;
                              16386   [ +  -  +  + ]:          26304 :         if (acls == NULL || *acls == '\0')
                              16387                 :             17 :             acls = acldefault;
                              16388                 :                :     }
                              16389                 :                :     else
                              16390                 :           2019 :         baseacls = acldefault;
                              16391                 :                : 
 2749                         16392         [ -  + ]:          28323 :     if (!buildACLCommands(name, subname, nspname, type,
                              16393                 :                :                           acls, baseacls, owner,
                              16394                 :                :                           "", fout->remoteVersion, sql))
 1247 tgl@sss.pgh.pa.us       16395                 :UBC           0 :         pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              16396                 :                :                  acls, baseacls, name, type);
                              16397                 :                : 
 8135 tgl@sss.pgh.pa.us       16398         [ +  + ]:CBC       28323 :     if (sql->len > 0)
                              16399                 :                :     {
  523                         16400                 :           2090 :         PQExpBuffer tagbuf = createPQExpBuffer();
                              16401                 :                :         DumpId      aclDeps[2];
 1883                         16402                 :           2090 :         int         nDeps = 0;
                              16403                 :                : 
  523                         16404         [ -  + ]:           2090 :         if (tag)
  523 tgl@sss.pgh.pa.us       16405                 :UBC           0 :             appendPQExpBufferStr(tagbuf, tag);
  523 tgl@sss.pgh.pa.us       16406         [ +  + ]:CBC        2090 :         else if (subname)
                              16407                 :           1239 :             appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
                              16408                 :                :         else
                              16409                 :            851 :             appendPQExpBuffer(tagbuf, "%s %s", type, name);
                              16410                 :                : 
 1883                         16411                 :           2090 :         aclDeps[nDeps++] = objDumpId;
                              16412         [ +  + ]:           2090 :         if (altDumpId != InvalidDumpId)
                              16413                 :           1149 :             aclDeps[nDeps++] = altDumpId;
                              16414                 :                : 
                              16415                 :           2090 :         aclDumpId = createDumpId();
                              16416                 :                : 
                              16417                 :           2090 :         ArchiveEntry(fout, nilCatalogId, aclDumpId,
  523                         16418                 :           2090 :                      ARCHIVE_OPTS(.tag = tagbuf->data,
                              16419                 :                :                                   .namespace = nspname,
                              16420                 :                :                                   .owner = owner,
                              16421                 :                :                                   .description = "ACL",
                              16422                 :                :                                   .section = SECTION_NONE,
                              16423                 :                :                                   .createStmt = sql->data,
                              16424                 :                :                                   .deps = aclDeps,
                              16425                 :                :                                   .nDeps = nDeps));
                              16426                 :                : 
                              16427                 :           2090 :         destroyPQExpBuffer(tagbuf);
                              16428                 :                :     }
                              16429                 :                : 
 8524                         16430                 :          28323 :     destroyPQExpBuffer(sql);
                              16431                 :                : 
 1883                         16432                 :          28323 :     return aclDumpId;
                              16433                 :                : }
                              16434                 :                : 
                              16435                 :                : /*
                              16436                 :                :  * dumpSecLabel
                              16437                 :                :  *
                              16438                 :                :  * This routine is used to dump any security labels associated with the
                              16439                 :                :  * object handed to this routine. The routine takes the object type
                              16440                 :                :  * and object name (ready to print, except for schema decoration), plus
                              16441                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              16442                 :                :  * plus catalog ID and subid which are the lookup key for pg_seclabel,
                              16443                 :                :  * plus the dump ID for the object (for setting a dependency).
                              16444                 :                :  * If a matching pg_seclabel entry is found, it is dumped.
                              16445                 :                :  *
                              16446                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              16447                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              16448                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              16449                 :                :  * ordering of the label in the dump file, because this routine is called
                              16450                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              16451                 :                :  * calling ArchiveEntry() for the specified object.
                              16452                 :                :  */
                              16453                 :                : static void
 2749 tgl@sss.pgh.pa.us       16454                 :UBC           0 : dumpSecLabel(Archive *fout, const char *type, const char *name,
                              16455                 :                :              const char *namespace, const char *owner,
                              16456                 :                :              CatalogId catalogId, int subid, DumpId dumpId)
                              16457                 :                : {
 3524                         16458                 :              0 :     DumpOptions *dopt = fout->dopt;
                              16459                 :                :     SecLabelItem *labels;
                              16460                 :                :     int         nlabels;
                              16461                 :                :     int         i;
                              16462                 :                :     PQExpBuffer query;
                              16463                 :                : 
                              16464                 :                :     /* do nothing, if --no-security-labels is supplied */
 3980 alvherre@alvh.no-ip.    16465         [ #  # ]:              0 :     if (dopt->no_security_labels)
 5458 rhaas@postgresql.org    16466                 :              0 :         return;
                              16467                 :                : 
                              16468                 :                :     /*
                              16469                 :                :      * Security labels are schema not data ... except large object labels are
                              16470                 :                :      * data
                              16471                 :                :      */
 2749 tgl@sss.pgh.pa.us       16472         [ #  # ]:              0 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              16473                 :                :     {
  285 nathan@postgresql.or    16474         [ #  # ]:              0 :         if (!dopt->dumpSchema)
 5458 rhaas@postgresql.org    16475                 :              0 :             return;
                              16476                 :                :     }
                              16477                 :                :     else
                              16478                 :                :     {
                              16479                 :                :         /* We do dump large object security labels in binary-upgrade mode */
  285 nathan@postgresql.or    16480   [ #  #  #  # ]:              0 :         if (!dopt->dumpData && !dopt->binary_upgrade)
 5458 rhaas@postgresql.org    16481                 :              0 :             return;
                              16482                 :                :     }
                              16483                 :                : 
                              16484                 :                :     /* Search for security labels associated with catalogId, using table */
 1346 tgl@sss.pgh.pa.us       16485                 :              0 :     nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
                              16486                 :                : 
 5458 rhaas@postgresql.org    16487                 :              0 :     query = createPQExpBuffer();
                              16488                 :                : 
                              16489         [ #  # ]:              0 :     for (i = 0; i < nlabels; i++)
                              16490                 :                :     {
                              16491                 :                :         /*
                              16492                 :                :          * Ignore label entries for which the subid doesn't match.
                              16493                 :                :          */
                              16494         [ #  # ]:              0 :         if (labels[i].objsubid != subid)
                              16495                 :              0 :             continue;
                              16496                 :                : 
                              16497                 :              0 :         appendPQExpBuffer(query,
                              16498                 :                :                           "SECURITY LABEL FOR %s ON %s ",
 2749 tgl@sss.pgh.pa.us       16499                 :              0 :                           fmtId(labels[i].provider), type);
                              16500   [ #  #  #  # ]:              0 :         if (namespace && *namespace)
                              16501                 :              0 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
                              16502                 :              0 :         appendPQExpBuffer(query, "%s IS ", name);
 5458 rhaas@postgresql.org    16503                 :              0 :         appendStringLiteralAH(query, labels[i].label, fout);
 4310 heikki.linnakangas@i    16504                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              16505                 :                :     }
                              16506                 :                : 
 5458 rhaas@postgresql.org    16507         [ #  # ]:              0 :     if (query->len > 0)
                              16508                 :                :     {
 2749 tgl@sss.pgh.pa.us       16509                 :              0 :         PQExpBuffer tag = createPQExpBuffer();
                              16510                 :                : 
                              16511                 :              0 :         appendPQExpBuffer(tag, "%s %s", type, name);
 5458 rhaas@postgresql.org    16512                 :              0 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    16513                 :              0 :                      ARCHIVE_OPTS(.tag = tag->data,
                              16514                 :                :                                   .namespace = namespace,
                              16515                 :                :                                   .owner = owner,
                              16516                 :                :                                   .description = "SECURITY LABEL",
                              16517                 :                :                                   .section = SECTION_NONE,
                              16518                 :                :                                   .createStmt = query->data,
                              16519                 :                :                                   .deps = &dumpId,
                              16520                 :                :                                   .nDeps = 1));
 2749 tgl@sss.pgh.pa.us       16521                 :              0 :         destroyPQExpBuffer(tag);
                              16522                 :                :     }
                              16523                 :                : 
 5458 rhaas@postgresql.org    16524                 :              0 :     destroyPQExpBuffer(query);
                              16525                 :                : }
                              16526                 :                : 
                              16527                 :                : /*
                              16528                 :                :  * dumpTableSecLabel
                              16529                 :                :  *
                              16530                 :                :  * As above, but dump security label for both the specified table (or view)
                              16531                 :                :  * and its columns.
                              16532                 :                :  */
                              16533                 :                : static void
 1669 peter@eisentraut.org    16534                 :              0 : dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
                              16535                 :                : {
 3524 tgl@sss.pgh.pa.us       16536                 :              0 :     DumpOptions *dopt = fout->dopt;
                              16537                 :                :     SecLabelItem *labels;
                              16538                 :                :     int         nlabels;
                              16539                 :                :     int         i;
                              16540                 :                :     PQExpBuffer query;
                              16541                 :                :     PQExpBuffer target;
                              16542                 :                : 
                              16543                 :                :     /* do nothing, if --no-security-labels is supplied */
 3980 alvherre@alvh.no-ip.    16544         [ #  # ]:              0 :     if (dopt->no_security_labels)
 5458 rhaas@postgresql.org    16545                 :              0 :         return;
                              16546                 :                : 
                              16547                 :                :     /* SecLabel are SCHEMA not data */
  285 nathan@postgresql.or    16548         [ #  # ]:              0 :     if (!dopt->dumpSchema)
 5458 rhaas@postgresql.org    16549                 :              0 :         return;
                              16550                 :                : 
                              16551                 :                :     /* Search for comments associated with relation, using table */
 1346 tgl@sss.pgh.pa.us       16552                 :              0 :     nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
 5458 rhaas@postgresql.org    16553                 :              0 :                             tbinfo->dobj.catId.oid,
                              16554                 :                :                             &labels);
                              16555                 :                : 
                              16556                 :                :     /* If security labels exist, build SECURITY LABEL statements */
                              16557         [ #  # ]:              0 :     if (nlabels <= 0)
                              16558                 :              0 :         return;
                              16559                 :                : 
                              16560                 :              0 :     query = createPQExpBuffer();
                              16561                 :              0 :     target = createPQExpBuffer();
                              16562                 :                : 
                              16563         [ #  # ]:              0 :     for (i = 0; i < nlabels; i++)
                              16564                 :                :     {
                              16565                 :                :         const char *colname;
 5263 bruce@momjian.us        16566                 :              0 :         const char *provider = labels[i].provider;
                              16567                 :              0 :         const char *label = labels[i].label;
                              16568                 :              0 :         int         objsubid = labels[i].objsubid;
                              16569                 :                : 
 5458 rhaas@postgresql.org    16570                 :              0 :         resetPQExpBuffer(target);
                              16571         [ #  # ]:              0 :         if (objsubid == 0)
                              16572                 :                :         {
                              16573                 :              0 :             appendPQExpBuffer(target, "%s %s", reltypename,
 2749 tgl@sss.pgh.pa.us       16574                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              16575                 :                :         }
                              16576                 :                :         else
                              16577                 :                :         {
 5458 rhaas@postgresql.org    16578                 :              0 :             colname = getAttrName(objsubid, tbinfo);
                              16579                 :                :             /* first fmtXXX result must be consumed before calling again */
 2749 tgl@sss.pgh.pa.us       16580                 :              0 :             appendPQExpBuffer(target, "COLUMN %s",
                              16581                 :              0 :                               fmtQualifiedDumpable(tbinfo));
 5362 rhaas@postgresql.org    16582                 :              0 :             appendPQExpBuffer(target, ".%s", fmtId(colname));
                              16583                 :                :         }
 5458                         16584                 :              0 :         appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
                              16585                 :                :                           fmtId(provider), target->data);
                              16586                 :              0 :         appendStringLiteralAH(query, label, fout);
 4310 heikki.linnakangas@i    16587                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              16588                 :                :     }
 5458 rhaas@postgresql.org    16589         [ #  # ]:              0 :     if (query->len > 0)
                              16590                 :                :     {
                              16591                 :              0 :         resetPQExpBuffer(target);
                              16592                 :              0 :         appendPQExpBuffer(target, "%s %s", reltypename,
                              16593                 :              0 :                           fmtId(tbinfo->dobj.name));
                              16594                 :              0 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    16595                 :              0 :                      ARCHIVE_OPTS(.tag = target->data,
                              16596                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              16597                 :                :                                   .owner = tbinfo->rolname,
                              16598                 :                :                                   .description = "SECURITY LABEL",
                              16599                 :                :                                   .section = SECTION_NONE,
                              16600                 :                :                                   .createStmt = query->data,
                              16601                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              16602                 :                :                                   .nDeps = 1));
                              16603                 :                :     }
 5458 rhaas@postgresql.org    16604                 :              0 :     destroyPQExpBuffer(query);
                              16605                 :              0 :     destroyPQExpBuffer(target);
                              16606                 :                : }
                              16607                 :                : 
                              16608                 :                : /*
                              16609                 :                :  * findSecLabels
                              16610                 :                :  *
                              16611                 :                :  * Find the security label(s), if any, associated with the given object.
                              16612                 :                :  * All the objsubid values associated with the given classoid/objoid are
                              16613                 :                :  * found with one search.
                              16614                 :                :  */
                              16615                 :                : static int
 1346 tgl@sss.pgh.pa.us       16616                 :              0 : findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
                              16617                 :                : {
 5263 bruce@momjian.us        16618                 :              0 :     SecLabelItem *middle = NULL;
                              16619                 :                :     SecLabelItem *low;
                              16620                 :                :     SecLabelItem *high;
                              16621                 :                :     int         nmatch;
                              16622                 :                : 
 1370 tgl@sss.pgh.pa.us       16623         [ #  # ]:              0 :     if (nseclabels <= 0)     /* no labels, so no match is possible */
                              16624                 :                :     {
 5049                         16625                 :              0 :         *items = NULL;
                              16626                 :              0 :         return 0;
                              16627                 :                :     }
                              16628                 :                : 
                              16629                 :                :     /*
                              16630                 :                :      * Do binary search to find some item matching the object.
                              16631                 :                :      */
 1370                         16632                 :              0 :     low = &seclabels[0];
                              16633                 :              0 :     high = &seclabels[nseclabels - 1];
 5458 rhaas@postgresql.org    16634         [ #  # ]:              0 :     while (low <= high)
                              16635                 :                :     {
                              16636                 :              0 :         middle = low + (high - low) / 2;
                              16637                 :                : 
                              16638         [ #  # ]:              0 :         if (classoid < middle->classoid)
                              16639                 :              0 :             high = middle - 1;
                              16640         [ #  # ]:              0 :         else if (classoid > middle->classoid)
                              16641                 :              0 :             low = middle + 1;
                              16642         [ #  # ]:              0 :         else if (objoid < middle->objoid)
                              16643                 :              0 :             high = middle - 1;
                              16644         [ #  # ]:              0 :         else if (objoid > middle->objoid)
                              16645                 :              0 :             low = middle + 1;
                              16646                 :                :         else
 5263 bruce@momjian.us        16647                 :              0 :             break;              /* found a match */
                              16648                 :                :     }
                              16649                 :                : 
                              16650         [ #  # ]:              0 :     if (low > high)              /* no matches */
                              16651                 :                :     {
 5458 rhaas@postgresql.org    16652                 :              0 :         *items = NULL;
                              16653                 :              0 :         return 0;
                              16654                 :                :     }
                              16655                 :                : 
                              16656                 :                :     /*
                              16657                 :                :      * Now determine how many items match the object.  The search loop
                              16658                 :                :      * invariant still holds: only items between low and high inclusive could
                              16659                 :                :      * match.
                              16660                 :                :      */
                              16661                 :              0 :     nmatch = 1;
                              16662         [ #  # ]:              0 :     while (middle > low)
                              16663                 :                :     {
                              16664         [ #  # ]:              0 :         if (classoid != middle[-1].classoid ||
                              16665         [ #  # ]:              0 :             objoid != middle[-1].objoid)
                              16666                 :                :             break;
                              16667                 :              0 :         middle--;
                              16668                 :              0 :         nmatch++;
                              16669                 :                :     }
                              16670                 :                : 
                              16671                 :              0 :     *items = middle;
                              16672                 :                : 
                              16673                 :              0 :     middle += nmatch;
                              16674         [ #  # ]:              0 :     while (middle <= high)
                              16675                 :                :     {
                              16676         [ #  # ]:              0 :         if (classoid != middle->classoid ||
                              16677         [ #  # ]:              0 :             objoid != middle->objoid)
                              16678                 :                :             break;
                              16679                 :              0 :         middle++;
                              16680                 :              0 :         nmatch++;
                              16681                 :                :     }
                              16682                 :                : 
                              16683                 :              0 :     return nmatch;
                              16684                 :                : }
                              16685                 :                : 
                              16686                 :                : /*
                              16687                 :                :  * collectSecLabels
                              16688                 :                :  *
                              16689                 :                :  * Construct a table of all security labels available for database objects;
                              16690                 :                :  * also set the has-seclabel component flag for each relevant object.
                              16691                 :                :  *
                              16692                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              16693                 :                :  */
                              16694                 :                : static void
 1370 tgl@sss.pgh.pa.us       16695                 :CBC         185 : collectSecLabels(Archive *fout)
                              16696                 :                : {
                              16697                 :                :     PGresult   *res;
                              16698                 :                :     PQExpBuffer query;
                              16699                 :                :     int         i_label;
                              16700                 :                :     int         i_provider;
                              16701                 :                :     int         i_classoid;
                              16702                 :                :     int         i_objoid;
                              16703                 :                :     int         i_objsubid;
                              16704                 :                :     int         ntups;
                              16705                 :                :     int         i;
                              16706                 :                :     DumpableObject *dobj;
                              16707                 :                : 
 5458 rhaas@postgresql.org    16708                 :            185 :     query = createPQExpBuffer();
                              16709                 :                : 
 4310 heikki.linnakangas@i    16710                 :            185 :     appendPQExpBufferStr(query,
                              16711                 :                :                          "SELECT label, provider, classoid, objoid, objsubid "
                              16712                 :                :                          "FROM pg_catalog.pg_seclabel "
                              16713                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              16714                 :                : 
 4960 rhaas@postgresql.org    16715                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16716                 :                : 
                              16717                 :                :     /* Construct lookup table containing OIDs in numeric form */
 5263 bruce@momjian.us        16718                 :            185 :     i_label = PQfnumber(res, "label");
                              16719                 :            185 :     i_provider = PQfnumber(res, "provider");
                              16720                 :            185 :     i_classoid = PQfnumber(res, "classoid");
                              16721                 :            185 :     i_objoid = PQfnumber(res, "objoid");
                              16722                 :            185 :     i_objsubid = PQfnumber(res, "objsubid");
                              16723                 :                : 
 5458 rhaas@postgresql.org    16724                 :            185 :     ntups = PQntuples(res);
                              16725                 :                : 
 1370 tgl@sss.pgh.pa.us       16726                 :            185 :     seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
                              16727                 :            185 :     nseclabels = 0;
                              16728                 :            185 :     dobj = NULL;
                              16729                 :                : 
 5458 rhaas@postgresql.org    16730         [ -  + ]:            185 :     for (i = 0; i < ntups; i++)
                              16731                 :                :     {
                              16732                 :                :         CatalogId   objId;
                              16733                 :                :         int         subid;
                              16734                 :                : 
 1370 tgl@sss.pgh.pa.us       16735                 :UBC           0 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              16736                 :              0 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              16737                 :              0 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              16738                 :                : 
                              16739                 :                :         /* We needn't remember labels that don't match any dumpable object */
                              16740         [ #  # ]:              0 :         if (dobj == NULL ||
                              16741         [ #  # ]:              0 :             dobj->catId.tableoid != objId.tableoid ||
                              16742         [ #  # ]:              0 :             dobj->catId.oid != objId.oid)
                              16743                 :              0 :             dobj = findObjectByCatalogId(objId);
                              16744         [ #  # ]:              0 :         if (dobj == NULL)
                              16745                 :              0 :             continue;
                              16746                 :                : 
                              16747                 :                :         /*
                              16748                 :                :          * Labels on columns of composite types are linked to the type's
                              16749                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
                              16750                 :                :          * in the type's own DumpableObject.
                              16751                 :                :          */
                              16752   [ #  #  #  # ]:              0 :         if (subid != 0 && dobj->objType == DO_TABLE &&
                              16753         [ #  # ]:              0 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              16754                 :              0 :         {
                              16755                 :                :             TypeInfo   *cTypeInfo;
                              16756                 :                : 
                              16757                 :              0 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              16758         [ #  # ]:              0 :             if (cTypeInfo)
                              16759                 :              0 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
                              16760                 :                :         }
                              16761                 :                :         else
                              16762                 :              0 :             dobj->components |= DUMP_COMPONENT_SECLABEL;
                              16763                 :                : 
                              16764                 :              0 :         seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
                              16765                 :              0 :         seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
                              16766                 :              0 :         seclabels[nseclabels].classoid = objId.tableoid;
                              16767                 :              0 :         seclabels[nseclabels].objoid = objId.oid;
                              16768                 :              0 :         seclabels[nseclabels].objsubid = subid;
                              16769                 :              0 :         nseclabels++;
                              16770                 :                :     }
                              16771                 :                : 
 1370 tgl@sss.pgh.pa.us       16772                 :CBC         185 :     PQclear(res);
 5263 bruce@momjian.us        16773                 :            185 :     destroyPQExpBuffer(query);
 5458 rhaas@postgresql.org    16774                 :            185 : }
                              16775                 :                : 
                              16776                 :                : /*
                              16777                 :                :  * dumpTable
                              16778                 :                :  *    write out to fout the declarations (not data) of a user-defined table
                              16779                 :                :  */
                              16780                 :                : static void
 1669 peter@eisentraut.org    16781                 :          31135 : dumpTable(Archive *fout, const TableInfo *tbinfo)
                              16782                 :                : {
 3440 sfrost@snowman.net      16783                 :          31135 :     DumpOptions *dopt = fout->dopt;
 1883 tgl@sss.pgh.pa.us       16784                 :          31135 :     DumpId      tableAclDumpId = InvalidDumpId;
                              16785                 :                :     char       *namecopy;
                              16786                 :                : 
                              16787                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    16788         [ +  + ]:          31135 :     if (!dopt->dumpSchema)
 3438 sfrost@snowman.net      16789                 :           1518 :         return;
                              16790                 :                : 
 1370 tgl@sss.pgh.pa.us       16791         [ +  + ]:          29617 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16792                 :                :     {
                              16793         [ +  + ]:           6989 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
                              16794                 :            393 :             dumpSequence(fout, tbinfo);
                              16795                 :                :         else
                              16796                 :           6596 :             dumpTableSchema(fout, tbinfo);
                              16797                 :                :     }
                              16798                 :                : 
                              16799                 :                :     /* Handle the ACL here */
 3440 sfrost@snowman.net      16800                 :          29617 :     namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
                              16801         [ +  + ]:          29617 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              16802                 :                :     {
 2784 tgl@sss.pgh.pa.us       16803                 :          23388 :         const char *objtype =
  841                         16804         [ +  + ]:          23388 :             (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
                              16805                 :                : 
                              16806                 :                :         tableAclDumpId =
 1883                         16807                 :          23388 :             dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
                              16808                 :                :                     objtype, namecopy, NULL,
  523                         16809                 :          23388 :                     tbinfo->dobj.namespace->dobj.name,
                              16810                 :          23388 :                     NULL, tbinfo->rolname, &tbinfo->dacl);
                              16811                 :                :     }
                              16812                 :                : 
                              16813                 :                :     /*
                              16814                 :                :      * Handle column ACLs, if any.  Note: we pull these with a separate query
                              16815                 :                :      * rather than trying to fetch them during getTableAttrs, so that we won't
                              16816                 :                :      * miss ACLs on system columns.  Doing it this way also allows us to dump
                              16817                 :                :      * ACLs for catalogs that we didn't mark "interesting" back in getTables.
                              16818                 :                :      */
 1370                         16819   [ +  +  +  + ]:          29617 :     if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
                              16820                 :                :     {
 3440 sfrost@snowman.net      16821                 :            298 :         PQExpBuffer query = createPQExpBuffer();
                              16822                 :                :         PGresult   *res;
                              16823                 :                :         int         i;
                              16824                 :                : 
 1370 tgl@sss.pgh.pa.us       16825         [ +  + ]:            298 :         if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS])
                              16826                 :                :         {
                              16827                 :                :             /* Set up query for column ACLs */
                              16828                 :            159 :             appendPQExpBufferStr(query,
                              16829                 :                :                                  "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
                              16830                 :                : 
                              16831         [ +  - ]:            159 :             if (fout->remoteVersion >= 90600)
                              16832                 :                :             {
                              16833                 :                :                 /*
                              16834                 :                :                  * In principle we should call acldefault('c', relowner) to
                              16835                 :                :                  * get the default ACL for a column.  However, we don't
                              16836                 :                :                  * currently store the numeric OID of the relowner in
                              16837                 :                :                  * TableInfo.  We could convert the owner name using regrole,
                              16838                 :                :                  * but that creates a risk of failure due to concurrent role
                              16839                 :                :                  * renames.  Given that the default ACL for columns is empty
                              16840                 :                :                  * and is likely to stay that way, it's not worth extra cycles
                              16841                 :                :                  * and risk to avoid hard-wiring that knowledge here.
                              16842                 :                :                  */
                              16843                 :            159 :                 appendPQExpBufferStr(query,
                              16844                 :                :                                      "SELECT at.attname, "
                              16845                 :                :                                      "at.attacl, "
                              16846                 :                :                                      "'{}' AS acldefault, "
                              16847                 :                :                                      "pip.privtype, pip.initprivs "
                              16848                 :                :                                      "FROM pg_catalog.pg_attribute at "
                              16849                 :                :                                      "LEFT JOIN pg_catalog.pg_init_privs pip ON "
                              16850                 :                :                                      "(at.attrelid = pip.objoid "
                              16851                 :                :                                      "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
                              16852                 :                :                                      "AND at.attnum = pip.objsubid) "
                              16853                 :                :                                      "WHERE at.attrelid = $1 AND "
                              16854                 :                :                                      "NOT at.attisdropped "
                              16855                 :                :                                      "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
                              16856                 :                :                                      "ORDER BY at.attnum");
                              16857                 :                :             }
                              16858                 :                :             else
                              16859                 :                :             {
 1370 tgl@sss.pgh.pa.us       16860                 :UBC           0 :                 appendPQExpBufferStr(query,
                              16861                 :                :                                      "SELECT attname, attacl, '{}' AS acldefault, "
                              16862                 :                :                                      "NULL AS privtype, NULL AS initprivs "
                              16863                 :                :                                      "FROM pg_catalog.pg_attribute "
                              16864                 :                :                                      "WHERE attrelid = $1 AND NOT attisdropped "
                              16865                 :                :                                      "AND attacl IS NOT NULL "
                              16866                 :                :                                      "ORDER BY attnum");
                              16867                 :                :             }
                              16868                 :                : 
 1370 tgl@sss.pgh.pa.us       16869                 :CBC         159 :             ExecuteSqlStatement(fout, query->data);
                              16870                 :                : 
                              16871                 :            159 :             fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
                              16872                 :                :         }
                              16873                 :                : 
                              16874                 :            298 :         printfPQExpBuffer(query,
                              16875                 :                :                           "EXECUTE getColumnACLs('%u')",
                              16876                 :            298 :                           tbinfo->dobj.catId.oid);
                              16877                 :                : 
 3440 sfrost@snowman.net      16878                 :            298 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16879                 :                : 
                              16880         [ +  + ]:           4657 :         for (i = 0; i < PQntuples(res); i++)
                              16881                 :                :         {
                              16882                 :           4359 :             char       *attname = PQgetvalue(res, i, 0);
                              16883                 :           4359 :             char       *attacl = PQgetvalue(res, i, 1);
 1370 tgl@sss.pgh.pa.us       16884                 :           4359 :             char       *acldefault = PQgetvalue(res, i, 2);
                              16885                 :           4359 :             char        privtype = *(PQgetvalue(res, i, 3));
                              16886                 :           4359 :             char       *initprivs = PQgetvalue(res, i, 4);
                              16887                 :                :             DumpableAcl coldacl;
                              16888                 :                :             char       *attnamecopy;
                              16889                 :                : 
                              16890                 :           4359 :             coldacl.acl = attacl;
                              16891                 :           4359 :             coldacl.acldefault = acldefault;
                              16892                 :           4359 :             coldacl.privtype = privtype;
                              16893                 :           4359 :             coldacl.initprivs = initprivs;
 3440 sfrost@snowman.net      16894                 :           4359 :             attnamecopy = pg_strdup(fmtId(attname));
                              16895                 :                : 
                              16896                 :                :             /*
                              16897                 :                :              * Column's GRANT type is always TABLE.  Each column ACL depends
                              16898                 :                :              * on the table-level ACL, since we can restore column ACLs in
                              16899                 :                :              * parallel but the table-level ACL has to be done first.
                              16900                 :                :              */
 1883 tgl@sss.pgh.pa.us       16901                 :           4359 :             dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
                              16902                 :                :                     "TABLE", namecopy, attnamecopy,
  523                         16903                 :           4359 :                     tbinfo->dobj.namespace->dobj.name,
                              16904                 :           4359 :                     NULL, tbinfo->rolname, &coldacl);
 3440 sfrost@snowman.net      16905                 :           4359 :             free(attnamecopy);
                              16906                 :                :         }
                              16907                 :            298 :         PQclear(res);
                              16908                 :            298 :         destroyPQExpBuffer(query);
                              16909                 :                :     }
                              16910                 :                : 
                              16911                 :          29617 :     free(namecopy);
                              16912                 :                : }
                              16913                 :                : 
                              16914                 :                : /*
                              16915                 :                :  * Create the AS clause for a view or materialized view. The semicolon is
                              16916                 :                :  * stripped because a materialized view must add a WITH NO DATA clause.
                              16917                 :                :  *
                              16918                 :                :  * This returns a new buffer which must be freed by the caller.
                              16919                 :                :  */
                              16920                 :                : static PQExpBuffer
 1669 peter@eisentraut.org    16921                 :            956 : createViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              16922                 :                : {
 4570 kgrittn@postgresql.o    16923                 :            956 :     PQExpBuffer query = createPQExpBuffer();
                              16924                 :            956 :     PQExpBuffer result = createPQExpBuffer();
                              16925                 :                :     PGresult   *res;
                              16926                 :                :     int         len;
                              16927                 :                : 
                              16928                 :                :     /* Fetch the view definition */
 3251 tgl@sss.pgh.pa.us       16929                 :            956 :     appendPQExpBuffer(query,
                              16930                 :                :                       "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
                              16931                 :            956 :                       tbinfo->dobj.catId.oid);
                              16932                 :                : 
 4570 kgrittn@postgresql.o    16933                 :            956 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              16934                 :                : 
                              16935         [ -  + ]:            956 :     if (PQntuples(res) != 1)
                              16936                 :                :     {
 4570 kgrittn@postgresql.o    16937         [ #  # ]:UBC           0 :         if (PQntuples(res) < 1)
 1247 tgl@sss.pgh.pa.us       16938                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned no data",
                              16939                 :                :                      tbinfo->dobj.name);
                              16940                 :                :         else
                              16941                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
                              16942                 :                :                      tbinfo->dobj.name);
                              16943                 :                :     }
                              16944                 :                : 
 4570 kgrittn@postgresql.o    16945                 :CBC         956 :     len = PQgetlength(res, 0, 0);
                              16946                 :                : 
                              16947         [ -  + ]:            956 :     if (len == 0)
 1247 tgl@sss.pgh.pa.us       16948                 :UBC           0 :         pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
                              16949                 :                :                  tbinfo->dobj.name);
                              16950                 :                : 
                              16951                 :                :     /* Strip off the trailing semicolon so that other things may follow. */
 4549 andrew@dunslane.net     16952         [ -  + ]:CBC         956 :     Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
 4570 kgrittn@postgresql.o    16953                 :            956 :     appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
                              16954                 :                : 
                              16955                 :            956 :     PQclear(res);
                              16956                 :            956 :     destroyPQExpBuffer(query);
                              16957                 :                : 
                              16958                 :            956 :     return result;
                              16959                 :                : }
                              16960                 :                : 
                              16961                 :                : /*
                              16962                 :                :  * Create a dummy AS clause for a view.  This is used when the real view
                              16963                 :                :  * definition has to be postponed because of circular dependencies.
                              16964                 :                :  * We must duplicate the view's external properties -- column names and types
                              16965                 :                :  * (including collation) -- so that it works for subsequent references.
                              16966                 :                :  *
                              16967                 :                :  * This returns a new buffer which must be freed by the caller.
                              16968                 :                :  */
                              16969                 :                : static PQExpBuffer
 1669 peter@eisentraut.org    16970                 :             20 : createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              16971                 :                : {
 3215 tgl@sss.pgh.pa.us       16972                 :             20 :     PQExpBuffer result = createPQExpBuffer();
                              16973                 :                :     int         j;
                              16974                 :                : 
                              16975                 :             20 :     appendPQExpBufferStr(result, "SELECT");
                              16976                 :                : 
                              16977         [ +  + ]:             40 :     for (j = 0; j < tbinfo->numatts; j++)
                              16978                 :                :     {
                              16979         [ +  + ]:             20 :         if (j > 0)
                              16980                 :             10 :             appendPQExpBufferChar(result, ',');
                              16981                 :             20 :         appendPQExpBufferStr(result, "\n    ");
                              16982                 :                : 
                              16983                 :             20 :         appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
                              16984                 :                : 
                              16985                 :                :         /*
                              16986                 :                :          * Must add collation if not default for the type, because CREATE OR
                              16987                 :                :          * REPLACE VIEW won't change it
                              16988                 :                :          */
                              16989         [ -  + ]:             20 :         if (OidIsValid(tbinfo->attcollation[j]))
                              16990                 :                :         {
                              16991                 :                :             CollInfo   *coll;
                              16992                 :                : 
 3215 tgl@sss.pgh.pa.us       16993                 :UBC           0 :             coll = findCollationByOid(tbinfo->attcollation[j]);
                              16994         [ #  # ]:              0 :             if (coll)
 2749                         16995                 :              0 :                 appendPQExpBuffer(result, " COLLATE %s",
                              16996                 :              0 :                                   fmtQualifiedDumpable(coll));
                              16997                 :                :         }
                              16998                 :                : 
 3215 tgl@sss.pgh.pa.us       16999                 :CBC          20 :         appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
                              17000                 :                :     }
                              17001                 :                : 
                              17002                 :             20 :     return result;
                              17003                 :                : }
                              17004                 :                : 
                              17005                 :                : /*
                              17006                 :                :  * dumpTableSchema
                              17007                 :                :  *    write the declaration (not data) of one user-defined table or view
                              17008                 :                :  */
                              17009                 :                : static void
 1669 peter@eisentraut.org    17010                 :           6596 : dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
                              17011                 :                : {
 3524 tgl@sss.pgh.pa.us       17012                 :           6596 :     DumpOptions *dopt = fout->dopt;
 9278 bruce@momjian.us        17013                 :           6596 :     PQExpBuffer q = createPQExpBuffer();
 9195                         17014                 :           6596 :     PQExpBuffer delq = createPQExpBuffer();
  404 tgl@sss.pgh.pa.us       17015                 :           6596 :     PQExpBuffer extra = createPQExpBuffer();
                              17016                 :                :     char       *qrelname;
                              17017                 :                :     char       *qualrelname;
                              17018                 :                :     int         numParents;
                              17019                 :                :     TableInfo **parents;
                              17020                 :                :     int         actual_atts;    /* number of attrs in this CREATE statement */
                              17021                 :                :     const char *reltypename;
                              17022                 :                :     char       *storage;
                              17023                 :                :     int         j,
                              17024                 :                :                 k;
                              17025                 :                : 
                              17026                 :                :     /* We had better have loaded per-column details about this table */
 1795                         17027         [ -  + ]:           6596 :     Assert(tbinfo->interesting);
                              17028                 :                : 
 2749                         17029                 :           6596 :     qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
                              17030                 :           6596 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              17031                 :                : 
 2482 andres@anarazel.de      17032         [ -  + ]:           6596 :     if (tbinfo->hasoids)
 2350 peter@eisentraut.org    17033                 :UBC           0 :         pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
                              17034                 :                :                        qrelname);
                              17035                 :                : 
 3980 alvherre@alvh.no-ip.    17036         [ +  + ]:CBC        6596 :     if (dopt->binary_upgrade)
 1370 tgl@sss.pgh.pa.us       17037                 :            868 :         binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
                              17038                 :                : 
                              17039                 :                :     /* Is it a table or a view? */
 8520                         17040         [ +  + ]:           6596 :     if (tbinfo->relkind == RELKIND_VIEW)
                              17041                 :                :     {
                              17042                 :                :         PQExpBuffer result;
                              17043                 :                : 
                              17044                 :                :         /*
                              17045                 :                :          * Note: keep this code in sync with the is_view case in dumpRule()
                              17046                 :                :          */
                              17047                 :                : 
                              17048                 :            536 :         reltypename = "VIEW";
                              17049                 :                : 
 2749                         17050                 :            536 :         appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
                              17051                 :                : 
 3980 alvherre@alvh.no-ip.    17052         [ +  + ]:            536 :         if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    17053                 :             52 :             binary_upgrade_set_pg_class_oids(fout, q,
  430 nathan@postgresql.or    17054                 :             52 :                                              tbinfo->dobj.catId.oid);
                              17055                 :                : 
 2749 tgl@sss.pgh.pa.us       17056                 :            536 :         appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
                              17057                 :                : 
 3215                         17058         [ +  + ]:            536 :         if (tbinfo->dummy_view)
                              17059                 :             10 :             result = createDummyViewAsClause(fout, tbinfo);
                              17060                 :                :         else
                              17061                 :                :         {
                              17062         [ +  + ]:            526 :             if (nonemptyReloptions(tbinfo->reloptions))
                              17063                 :                :             {
                              17064                 :             67 :                 appendPQExpBufferStr(q, " WITH (");
                              17065                 :             67 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              17066                 :             67 :                 appendPQExpBufferChar(q, ')');
                              17067                 :                :             }
                              17068                 :            526 :             result = createViewAsClause(fout, tbinfo);
                              17069                 :                :         }
 4433 sfrost@snowman.net      17070                 :            536 :         appendPQExpBuffer(q, " AS\n%s", result->data);
 4570 kgrittn@postgresql.o    17071                 :            536 :         destroyPQExpBuffer(result);
                              17072                 :                : 
 3215 tgl@sss.pgh.pa.us       17073   [ +  +  +  - ]:            536 :         if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
 4433 sfrost@snowman.net      17074                 :             38 :             appendPQExpBuffer(q, "\n  WITH %s CHECK OPTION", tbinfo->checkoption);
 4310 heikki.linnakangas@i    17075                 :            536 :         appendPQExpBufferStr(q, ";\n");
                              17076                 :                :     }
                              17077                 :                :     else
                              17078                 :                :     {
 1370 tgl@sss.pgh.pa.us       17079                 :           6060 :         char       *partkeydef = NULL;
 2466 sfrost@snowman.net      17080                 :           6060 :         char       *ftoptions = NULL;
                              17081                 :           6060 :         char       *srvname = NULL;
  404 tgl@sss.pgh.pa.us       17082                 :           6060 :         const char *foreign = "";
                              17083                 :                : 
                              17084                 :                :         /*
                              17085                 :                :          * Set reltypename, and collect any relkind-specific data that we
                              17086                 :                :          * didn't fetch during getTables().
                              17087                 :                :          */
 4570 kgrittn@postgresql.o    17088   [ +  +  +  + ]:           6060 :         switch (tbinfo->relkind)
                              17089                 :                :         {
 1370 tgl@sss.pgh.pa.us       17090                 :            590 :             case RELKIND_PARTITIONED_TABLE:
                              17091                 :                :                 {
                              17092                 :            590 :                     PQExpBuffer query = createPQExpBuffer();
                              17093                 :                :                     PGresult   *res;
                              17094                 :                : 
                              17095                 :            590 :                     reltypename = "TABLE";
                              17096                 :                : 
                              17097                 :                :                     /* retrieve partition key definition */
                              17098                 :            590 :                     appendPQExpBuffer(query,
                              17099                 :                :                                       "SELECT pg_get_partkeydef('%u')",
                              17100                 :            590 :                                       tbinfo->dobj.catId.oid);
                              17101                 :            590 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              17102                 :            590 :                     partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
                              17103                 :            590 :                     PQclear(res);
                              17104                 :            590 :                     destroyPQExpBuffer(query);
                              17105                 :            590 :                     break;
                              17106                 :                :                 }
 3103                         17107                 :             40 :             case RELKIND_FOREIGN_TABLE:
                              17108                 :                :                 {
 4549 andrew@dunslane.net     17109                 :             40 :                     PQExpBuffer query = createPQExpBuffer();
                              17110                 :                :                     PGresult   *res;
                              17111                 :                :                     int         i_srvname;
                              17112                 :                :                     int         i_ftoptions;
                              17113                 :                : 
                              17114                 :             40 :                     reltypename = "FOREIGN TABLE";
                              17115                 :                : 
                              17116                 :                :                     /* retrieve name of foreign server and generic options */
                              17117                 :             40 :                     appendPQExpBuffer(query,
                              17118                 :                :                                       "SELECT fs.srvname, "
                              17119                 :                :                                       "pg_catalog.array_to_string(ARRAY("
                              17120                 :                :                                       "SELECT pg_catalog.quote_ident(option_name) || "
                              17121                 :                :                                       "' ' || pg_catalog.quote_literal(option_value) "
                              17122                 :                :                                       "FROM pg_catalog.pg_options_to_table(ftoptions) "
                              17123                 :                :                                       "ORDER BY option_name"
                              17124                 :                :                                       "), E',\n    ') AS ftoptions "
                              17125                 :                :                                       "FROM pg_catalog.pg_foreign_table ft "
                              17126                 :                :                                       "JOIN pg_catalog.pg_foreign_server fs "
                              17127                 :                :                                       "ON (fs.oid = ft.ftserver) "
                              17128                 :                :                                       "WHERE ft.ftrelid = '%u'",
                              17129                 :             40 :                                       tbinfo->dobj.catId.oid);
                              17130                 :             40 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              17131                 :             40 :                     i_srvname = PQfnumber(res, "srvname");
                              17132                 :             40 :                     i_ftoptions = PQfnumber(res, "ftoptions");
                              17133                 :             40 :                     srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
                              17134                 :             40 :                     ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
                              17135                 :             40 :                     PQclear(res);
                              17136                 :             40 :                     destroyPQExpBuffer(query);
                              17137                 :                : 
 1996 alvherre@alvh.no-ip.    17138                 :             40 :                     foreign = "FOREIGN ";
 4549 andrew@dunslane.net     17139                 :             40 :                     break;
                              17140                 :                :                 }
 3103 tgl@sss.pgh.pa.us       17141                 :            420 :             case RELKIND_MATVIEW:
 4570 kgrittn@postgresql.o    17142                 :            420 :                 reltypename = "MATERIALIZED VIEW";
                              17143                 :            420 :                 break;
                              17144                 :           5010 :             default:
                              17145                 :           5010 :                 reltypename = "TABLE";
 1370 tgl@sss.pgh.pa.us       17146                 :           5010 :                 break;
                              17147                 :                :         }
                              17148                 :                : 
 8520                         17149                 :           6060 :         numParents = tbinfo->numParents;
 7945                         17150                 :           6060 :         parents = tbinfo->parents;
                              17151                 :                : 
 2749                         17152                 :           6060 :         appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
                              17153                 :                : 
 3980 alvherre@alvh.no-ip.    17154         [ +  + ]:           6060 :         if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    17155                 :            816 :             binary_upgrade_set_pg_class_oids(fout, q,
  430 nathan@postgresql.or    17156                 :            816 :                                              tbinfo->dobj.catId.oid);
                              17157                 :                : 
                              17158                 :                :         /*
                              17159                 :                :          * PostgreSQL 18 has disabled UNLOGGED for partitioned tables, so
                              17160                 :                :          * ignore it when dumping if it was set in this case.
                              17161                 :                :          */
 5362 rhaas@postgresql.org    17162                 :           6060 :         appendPQExpBuffer(q, "CREATE %s%s %s",
  338 michael@paquier.xyz     17163         [ +  + ]:           6060 :                           (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
                              17164         [ +  - ]:             20 :                            tbinfo->relkind != RELKIND_PARTITIONED_TABLE) ?
                              17165                 :                :                           "UNLOGGED " : "",
                              17166                 :                :                           reltypename,
                              17167                 :                :                           qualrelname);
                              17168                 :                : 
                              17169                 :                :         /*
                              17170                 :                :          * Attach to type, if reloftype; except in case of a binary upgrade,
                              17171                 :                :          * we dump the table normally and attach it to the type afterward.
                              17172                 :                :          */
 1370 tgl@sss.pgh.pa.us       17173   [ +  +  +  + ]:           6060 :         if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
                              17174                 :             24 :             appendPQExpBuffer(q, " OF %s",
                              17175                 :             24 :                               getFormattedTypeName(fout, tbinfo->reloftype,
                              17176                 :                :                                                    zeroIsError));
                              17177                 :                : 
 4570 kgrittn@postgresql.o    17178         [ +  + ]:           6060 :         if (tbinfo->relkind != RELKIND_MATVIEW)
                              17179                 :                :         {
                              17180                 :                :             /* Dump the attributes */
 4549 andrew@dunslane.net     17181                 :           5640 :             actual_atts = 0;
                              17182         [ +  + ]:          25985 :             for (j = 0; j < tbinfo->numatts; j++)
                              17183                 :                :             {
                              17184                 :                :                 /*
                              17185                 :                :                  * Normally, dump if it's locally defined in this table, and
                              17186                 :                :                  * not dropped.  But for binary upgrade, we'll dump all the
                              17187                 :                :                  * columns, and then fix up the dropped and nonlocal cases
                              17188                 :                :                  * below.
                              17189                 :                :                  */
 3980 alvherre@alvh.no-ip.    17190         [ +  + ]:          20345 :                 if (shouldPrintColumn(dopt, tbinfo, j))
                              17191                 :                :                 {
                              17192                 :                :                     bool        print_default;
                              17193                 :                :                     bool        print_notnull;
                              17194                 :                : 
                              17195                 :                :                     /*
                              17196                 :                :                      * Default value --- suppress if to be printed separately
                              17197                 :                :                      * or not at all.
                              17198                 :                :                      */
 2280                         17199                 :          39751 :                     print_default = (tbinfo->attrdefs[j] != NULL &&
  921 tgl@sss.pgh.pa.us       17200   [ +  +  +  + ]:          20380 :                                      tbinfo->attrdefs[j]->dobj.dump &&
 2280 alvherre@alvh.no-ip.    17201         [ +  + ]:           1062 :                                      !tbinfo->attrdefs[j]->separate);
                              17202                 :                : 
                              17203                 :                :                     /*
                              17204                 :                :                      * Not Null constraint --- print it if it is locally
                              17205                 :                :                      * defined, or if binary upgrade.  (In the latter case, we
                              17206                 :                :                      * reset conislocal below.)
                              17207                 :                :                      */
  302                         17208         [ +  + ]:          21664 :                     print_notnull = (tbinfo->notnull_constrs[j] != NULL &&
                              17209         [ +  + ]:           2346 :                                      (tbinfo->notnull_islocal[j] ||
                              17210         [ +  + ]:            661 :                                       dopt->binary_upgrade ||
                              17211         [ +  + ]:            577 :                                       tbinfo->ispartition));
                              17212                 :                : 
                              17213                 :                :                     /*
                              17214                 :                :                      * Skip column if fully defined by reloftype, except in
                              17215                 :                :                      * binary upgrade
                              17216                 :                :                      */
 1370 tgl@sss.pgh.pa.us       17217         [ +  + ]:          19318 :                     if (OidIsValid(tbinfo->reloftype) &&
                              17218   [ +  +  +  + ]:             50 :                         !print_default && !print_notnull &&
 2280 alvherre@alvh.no-ip.    17219         [ +  + ]:             30 :                         !dopt->binary_upgrade)
 4549 andrew@dunslane.net     17220                 :             24 :                         continue;
                              17221                 :                : 
                              17222                 :                :                     /* Format properly if not first attr */
                              17223         [ +  + ]:          19294 :                     if (actual_atts == 0)
 4310 heikki.linnakangas@i    17224                 :           5282 :                         appendPQExpBufferStr(q, " (");
                              17225                 :                :                     else
 3719                         17226                 :          14012 :                         appendPQExpBufferChar(q, ',');
 4310                         17227                 :          19294 :                     appendPQExpBufferStr(q, "\n    ");
 4549 andrew@dunslane.net     17228                 :          19294 :                     actual_atts++;
                              17229                 :                : 
                              17230                 :                :                     /* Attribute name */
 4310 heikki.linnakangas@i    17231                 :          19294 :                     appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
                              17232                 :                : 
 4549 andrew@dunslane.net     17233         [ +  + ]:          19294 :                     if (tbinfo->attisdropped[j])
                              17234                 :                :                     {
                              17235                 :                :                         /*
                              17236                 :                :                          * ALTER TABLE DROP COLUMN clears
                              17237                 :                :                          * pg_attribute.atttypid, so we will not have gotten a
                              17238                 :                :                          * valid type name; insert INTEGER as a stopgap. We'll
                              17239                 :                :                          * clean things up later.
                              17240                 :                :                          */
 4310 heikki.linnakangas@i    17241                 :             84 :                         appendPQExpBufferStr(q, " INTEGER /* dummy */");
                              17242                 :                :                         /* and skip to the next column */
 4549 andrew@dunslane.net     17243                 :             84 :                         continue;
                              17244                 :                :                     }
                              17245                 :                : 
                              17246                 :                :                     /*
                              17247                 :                :                      * Attribute type; print it except when creating a typed
                              17248                 :                :                      * table ('OF type_name'), but in binary-upgrade mode,
                              17249                 :                :                      * print it in that case too.
                              17250                 :                :                      */
 1370 tgl@sss.pgh.pa.us       17251   [ +  +  +  + ]:          19210 :                     if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
                              17252                 :                :                     {
 4549 andrew@dunslane.net     17253                 :          19194 :                         appendPQExpBuffer(q, " %s",
 3251 tgl@sss.pgh.pa.us       17254                 :          19194 :                                           tbinfo->atttypnames[j]);
                              17255                 :                :                     }
                              17256                 :                : 
 2280 alvherre@alvh.no-ip.    17257         [ +  + ]:          19210 :                     if (print_default)
                              17258                 :                :                     {
 2352 peter@eisentraut.org    17259         [ +  + ]:            920 :                         if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
                              17260                 :            295 :                             appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
                              17261                 :            295 :                                               tbinfo->attrdefs[j]->adef_expr);
  211                         17262         [ +  + ]:            625 :                         else if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_VIRTUAL)
                              17263                 :            229 :                             appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s)",
                              17264                 :            229 :                                               tbinfo->attrdefs[j]->adef_expr);
                              17265                 :                :                         else
 2352                         17266                 :            396 :                             appendPQExpBuffer(q, " DEFAULT %s",
                              17267                 :            396 :                                               tbinfo->attrdefs[j]->adef_expr);
                              17268                 :                :                     }
                              17269                 :                : 
 2280 alvherre@alvh.no-ip.    17270         [ +  + ]:          19210 :                     if (print_notnull)
                              17271                 :                :                     {
  302                         17272         [ +  + ]:           2309 :                         if (tbinfo->notnull_constrs[j][0] == '\0')
                              17273                 :           1621 :                             appendPQExpBufferStr(q, " NOT NULL");
                              17274                 :                :                         else
                              17275                 :            688 :                             appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
                              17276                 :            688 :                                               fmtId(tbinfo->notnull_constrs[j]));
                              17277                 :                : 
                              17278         [ -  + ]:           2309 :                         if (tbinfo->notnull_noinh[j])
  302 alvherre@alvh.no-ip.    17279                 :UBC           0 :                             appendPQExpBufferStr(q, " NO INHERIT");
                              17280                 :                :                     }
                              17281                 :                : 
                              17282                 :                :                     /* Add collation if not default for the type */
 4549 andrew@dunslane.net     17283         [ +  + ]:CBC       19210 :                     if (OidIsValid(tbinfo->attcollation[j]))
                              17284                 :                :                     {
                              17285                 :                :                         CollInfo   *coll;
                              17286                 :                : 
                              17287                 :            197 :                         coll = findCollationByOid(tbinfo->attcollation[j]);
                              17288         [ +  - ]:            197 :                         if (coll)
 2749 tgl@sss.pgh.pa.us       17289                 :            197 :                             appendPQExpBuffer(q, " COLLATE %s",
                              17290                 :            197 :                                               fmtQualifiedDumpable(coll));
                              17291                 :                :                     }
                              17292                 :                :                 }
                              17293                 :                : 
                              17294                 :                :                 /*
                              17295                 :                :                  * On the other hand, if we choose not to print a column
                              17296                 :                :                  * (likely because it is created by inheritance), but the
                              17297                 :                :                  * column has a locally-defined not-null constraint, we need
                              17298                 :                :                  * to dump the constraint as a standalone object.
                              17299                 :                :                  *
                              17300                 :                :                  * This syntax isn't SQL-conforming, but if you wanted
                              17301                 :                :                  * standard output you wouldn't be creating non-standard
                              17302                 :                :                  * objects to begin with.
                              17303                 :                :                  */
  267 alvherre@alvh.no-ip.    17304         [ +  + ]:          20237 :                 if (!shouldPrintColumn(dopt, tbinfo, j) &&
                              17305         [ +  + ]:           1027 :                     !tbinfo->attisdropped[j] &&
                              17306         [ +  + ]:            658 :                     tbinfo->notnull_constrs[j] != NULL &&
                              17307         [ +  + ]:            191 :                     tbinfo->notnull_islocal[j])
                              17308                 :                :                 {
                              17309                 :                :                     /* Format properly if not first attr */
                              17310         [ +  + ]:             61 :                     if (actual_atts == 0)
                              17311                 :             57 :                         appendPQExpBufferStr(q, " (");
                              17312                 :                :                     else
                              17313                 :              4 :                         appendPQExpBufferChar(q, ',');
                              17314                 :             61 :                     appendPQExpBufferStr(q, "\n    ");
                              17315                 :             61 :                     actual_atts++;
                              17316                 :                : 
                              17317         [ +  + ]:             61 :                     if (tbinfo->notnull_constrs[j][0] == '\0')
                              17318                 :              4 :                         appendPQExpBuffer(q, "NOT NULL %s",
                              17319                 :              4 :                                           fmtId(tbinfo->attnames[j]));
                              17320                 :                :                     else
                              17321                 :            114 :                         appendPQExpBuffer(q, "CONSTRAINT %s NOT NULL %s",
                              17322                 :             57 :                                           tbinfo->notnull_constrs[j],
                              17323                 :             57 :                                           fmtId(tbinfo->attnames[j]));
                              17324                 :                :                 }
                              17325                 :                :             }
                              17326                 :                : 
                              17327                 :                :             /*
                              17328                 :                :              * Add non-inherited CHECK constraints, if any.
                              17329                 :                :              *
                              17330                 :                :              * For partitions, we need to include check constraints even if
                              17331                 :                :              * they're not defined locally, because the ALTER TABLE ATTACH
                              17332                 :                :              * PARTITION that we'll emit later expects the constraint to be
                              17333                 :                :              * there.  (No need to fix conislocal: ATTACH PARTITION does that)
                              17334                 :                :              */
 4549 andrew@dunslane.net     17335         [ +  + ]:           6283 :             for (j = 0; j < tbinfo->ncheck; j++)
                              17336                 :                :             {
                              17337                 :            643 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              17338                 :                : 
 2280 alvherre@alvh.no-ip.    17339         [ +  + ]:            643 :                 if (constr->separate ||
                              17340   [ +  +  +  + ]:            573 :                     (!constr->conislocal && !tbinfo->ispartition))
 4549 andrew@dunslane.net     17341                 :            113 :                     continue;
                              17342                 :                : 
                              17343         [ +  + ]:            530 :                 if (actual_atts == 0)
 4310 heikki.linnakangas@i    17344                 :             16 :                     appendPQExpBufferStr(q, " (\n    ");
                              17345                 :                :                 else
                              17346                 :            514 :                     appendPQExpBufferStr(q, ",\n    ");
                              17347                 :                : 
 4549 andrew@dunslane.net     17348                 :            530 :                 appendPQExpBuffer(q, "CONSTRAINT %s ",
                              17349                 :            530 :                                   fmtId(constr->dobj.name));
 4310 heikki.linnakangas@i    17350                 :            530 :                 appendPQExpBufferStr(q, constr->condef);
                              17351                 :                : 
 4549 andrew@dunslane.net     17352                 :            530 :                 actual_atts++;
                              17353                 :                :             }
                              17354                 :                : 
                              17355         [ +  + ]:           5640 :             if (actual_atts)
 4310 heikki.linnakangas@i    17356                 :           5355 :                 appendPQExpBufferStr(q, "\n)");
 1370 tgl@sss.pgh.pa.us       17357   [ +  +  -  + ]:            285 :             else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
                              17358                 :                :             {
                              17359                 :                :                 /*
                              17360                 :                :                  * No attributes? we must have a parenthesized attribute list,
                              17361                 :                :                  * even though empty, when not using the OF TYPE syntax.
                              17362                 :                :                  */
 4310 heikki.linnakangas@i    17363                 :            273 :                 appendPQExpBufferStr(q, " (\n)");
                              17364                 :                :             }
                              17365                 :                : 
                              17366                 :                :             /*
                              17367                 :                :              * Emit the INHERITS clause (not for partitions), except in
                              17368                 :                :              * binary-upgrade mode.
                              17369                 :                :              */
 2280 alvherre@alvh.no-ip.    17370   [ +  +  +  + ]:           5640 :             if (numParents > 0 && !tbinfo->ispartition &&
 3047 sfrost@snowman.net      17371         [ +  + ]:            520 :                 !dopt->binary_upgrade)
                              17372                 :                :             {
 4310 heikki.linnakangas@i    17373                 :            457 :                 appendPQExpBufferStr(q, "\nINHERITS (");
 4549 andrew@dunslane.net     17374         [ +  + ]:            991 :                 for (k = 0; k < numParents; k++)
                              17375                 :                :                 {
                              17376                 :            534 :                     TableInfo  *parentRel = parents[k];
                              17377                 :                : 
                              17378         [ +  + ]:            534 :                     if (k > 0)
 4310 heikki.linnakangas@i    17379                 :             77 :                         appendPQExpBufferStr(q, ", ");
 2749 tgl@sss.pgh.pa.us       17380                 :            534 :                     appendPQExpBufferStr(q, fmtQualifiedDumpable(parentRel));
                              17381                 :                :                 }
 4310 heikki.linnakangas@i    17382                 :            457 :                 appendPQExpBufferChar(q, ')');
                              17383                 :                :             }
                              17384                 :                : 
 3195 rhaas@postgresql.org    17385         [ +  + ]:           5640 :             if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 1370 tgl@sss.pgh.pa.us       17386                 :            590 :                 appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
                              17387                 :                : 
 4549 andrew@dunslane.net     17388         [ +  + ]:           5640 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                              17389                 :             40 :                 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
                              17390                 :                :         }
                              17391                 :                : 
 3535 tgl@sss.pgh.pa.us       17392   [ +  +  -  + ]:          11972 :         if (nonemptyReloptions(tbinfo->reloptions) ||
                              17393                 :           5912 :             nonemptyReloptions(tbinfo->toast_reloptions))
                              17394                 :                :         {
 5931 bruce@momjian.us        17395                 :            148 :             bool        addcomma = false;
                              17396                 :                : 
 4310 heikki.linnakangas@i    17397                 :            148 :             appendPQExpBufferStr(q, "\nWITH (");
 3535 tgl@sss.pgh.pa.us       17398         [ +  - ]:            148 :             if (nonemptyReloptions(tbinfo->reloptions))
                              17399                 :                :             {
 6060 alvherre@alvh.no-ip.    17400                 :            148 :                 addcomma = true;
 3410 dean.a.rasheed@gmail    17401                 :            148 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              17402                 :                :             }
 3535 tgl@sss.pgh.pa.us       17403         [ +  + ]:            148 :             if (nonemptyReloptions(tbinfo->toast_reloptions))
                              17404                 :                :             {
                              17405         [ +  - ]:              5 :                 if (addcomma)
                              17406                 :              5 :                     appendPQExpBufferStr(q, ", ");
 3410 dean.a.rasheed@gmail    17407                 :              5 :                 appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
                              17408                 :                :                                         fout);
                              17409                 :                :             }
 4310 heikki.linnakangas@i    17410                 :            148 :             appendPQExpBufferChar(q, ')');
                              17411                 :                :         }
                              17412                 :                : 
                              17413                 :                :         /* Dump generic options if any */
 5362 rhaas@postgresql.org    17414   [ +  +  +  + ]:           6060 :         if (ftoptions && ftoptions[0])
 4993 peter_e@gmx.net         17415                 :             38 :             appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);
                              17416                 :                : 
                              17417                 :                :         /*
                              17418                 :                :          * For materialized views, create the AS clause just like a view. At
                              17419                 :                :          * this point, we always mark the view as not populated.
                              17420                 :                :          */
 4570 kgrittn@postgresql.o    17421         [ +  + ]:           6060 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              17422                 :                :         {
                              17423                 :                :             PQExpBuffer result;
                              17424                 :                : 
                              17425                 :            420 :             result = createViewAsClause(fout, tbinfo);
                              17426                 :            420 :             appendPQExpBuffer(q, " AS\n%s\n  WITH NO DATA;\n",
                              17427                 :                :                               result->data);
                              17428                 :            420 :             destroyPQExpBuffer(result);
                              17429                 :                :         }
                              17430                 :                :         else
 4310 heikki.linnakangas@i    17431                 :           5640 :             appendPQExpBufferStr(q, ";\n");
                              17432                 :                : 
                              17433                 :                :         /* Materialized views can depend on extensions */
 2005 alvherre@alvh.no-ip.    17434         [ +  + ]:           6060 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              17435                 :            420 :             append_depends_on_extension(fout, q, &tbinfo->dobj,
                              17436                 :                :                                         "pg_catalog.pg_class",
                              17437                 :                :                                         "MATERIALIZED VIEW",
                              17438                 :                :                                         qualrelname);
                              17439                 :                : 
                              17440                 :                :         /*
                              17441                 :                :          * in binary upgrade mode, update the catalog with any missing values
                              17442                 :                :          * that might be present.
                              17443                 :                :          */
 2633 andrew@dunslane.net     17444         [ +  + ]:           6060 :         if (dopt->binary_upgrade)
                              17445                 :                :         {
                              17446         [ +  + ]:           3952 :             for (j = 0; j < tbinfo->numatts; j++)
                              17447                 :                :             {
                              17448         [ +  + ]:           3136 :                 if (tbinfo->attmissingval[j][0] != '\0')
                              17449                 :                :                 {
                              17450                 :              2 :                     appendPQExpBufferStr(q, "\n-- set missing value.\n");
                              17451                 :              2 :                     appendPQExpBufferStr(q,
                              17452                 :                :                                          "SELECT pg_catalog.binary_upgrade_set_missing_value(");
                              17453                 :              2 :                     appendStringLiteralAH(q, qualrelname, fout);
                              17454                 :              2 :                     appendPQExpBufferStr(q, "::pg_catalog.regclass,");
                              17455                 :              2 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 1096 drowley@postgresql.o    17456                 :              2 :                     appendPQExpBufferChar(q, ',');
 2633 andrew@dunslane.net     17457                 :              2 :                     appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
                              17458                 :              2 :                     appendPQExpBufferStr(q, ");\n\n");
                              17459                 :                :                 }
                              17460                 :                :             }
                              17461                 :                :         }
                              17462                 :                : 
                              17463                 :                :         /*
                              17464                 :                :          * To create binary-compatible heap files, we have to ensure the same
                              17465                 :                :          * physical column order, including dropped columns, as in the
                              17466                 :                :          * original.  Therefore, we create dropped columns above and drop them
                              17467                 :                :          * here, also updating their attlen/attalign values so that the
                              17468                 :                :          * dropped column can be skipped properly.  (We do not bother with
                              17469                 :                :          * restoring the original attbyval setting.)  Also, inheritance
                              17470                 :                :          * relationships are set up by doing ALTER TABLE INHERIT rather than
                              17471                 :                :          * using an INHERITS clause --- the latter would possibly mess up the
                              17472                 :                :          * column order.  That also means we have to take care about setting
                              17473                 :                :          * attislocal correctly, plus fix up any inherited CHECK constraints.
                              17474                 :                :          * Analogously, we set up typed tables using ALTER TABLE / OF here.
                              17475                 :                :          *
                              17476                 :                :          * We process foreign and partitioned tables here, even though they
                              17477                 :                :          * lack heap storage, because they can participate in inheritance
                              17478                 :                :          * relationships and we want this stuff to be consistent across the
                              17479                 :                :          * inheritance tree.  We can exclude indexes, toast tables, sequences
                              17480                 :                :          * and matviews, even though they have storage, because we don't
                              17481                 :                :          * support altering or dropping columns in them, nor can they be part
                              17482                 :                :          * of inheritance trees.
                              17483                 :                :          */
 3821 tgl@sss.pgh.pa.us       17484         [ +  + ]:           6060 :         if (dopt->binary_upgrade &&
                              17485         [ +  + ]:            816 :             (tbinfo->relkind == RELKIND_RELATION ||
 3195 rhaas@postgresql.org    17486         [ +  + ]:            110 :              tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
                              17487         [ +  + ]:            109 :              tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
                              17488                 :                :         {
                              17489                 :                :             bool        firstitem;
                              17490                 :                :             bool        firstitem_extra;
                              17491                 :                : 
                              17492                 :                :             /*
                              17493                 :                :              * Drop any dropped columns.  Merge the pg_attribute manipulations
                              17494                 :                :              * into a single SQL command, so that we don't cause repeated
                              17495                 :                :              * relcache flushes on the target table.  Otherwise we risk O(N^2)
                              17496                 :                :              * relcache bloat while dropping N columns.
                              17497                 :                :              */
  404 tgl@sss.pgh.pa.us       17498                 :            798 :             resetPQExpBuffer(extra);
                              17499                 :            798 :             firstitem = true;
 6045 bruce@momjian.us        17500         [ +  + ]:           3912 :             for (j = 0; j < tbinfo->numatts; j++)
                              17501                 :                :             {
                              17502         [ +  + ]:           3114 :                 if (tbinfo->attisdropped[j])
                              17503                 :                :                 {
  404 tgl@sss.pgh.pa.us       17504         [ +  + ]:             84 :                     if (firstitem)
                              17505                 :                :                     {
                              17506                 :             38 :                         appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped columns.\n"
                              17507                 :                :                                              "UPDATE pg_catalog.pg_attribute\n"
                              17508                 :                :                                              "SET attlen = v.dlen, "
                              17509                 :                :                                              "attalign = v.dalign, "
                              17510                 :                :                                              "attbyval = false\n"
                              17511                 :                :                                              "FROM (VALUES ");
                              17512                 :             38 :                         firstitem = false;
                              17513                 :                :                     }
                              17514                 :                :                     else
                              17515                 :             46 :                         appendPQExpBufferStr(q, ",\n             ");
                              17516                 :             84 :                     appendPQExpBufferChar(q, '(');
                              17517                 :             84 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                              17518                 :             84 :                     appendPQExpBuffer(q, ", %d, '%c')",
 5910                         17519                 :             84 :                                       tbinfo->attlen[j],
                              17520                 :             84 :                                       tbinfo->attalign[j]);
                              17521                 :                :                     /* The ALTER ... DROP COLUMN commands must come after */
  404                         17522                 :             84 :                     appendPQExpBuffer(extra, "ALTER %sTABLE ONLY %s ",
                              17523                 :                :                                       foreign, qualrelname);
                              17524                 :             84 :                     appendPQExpBuffer(extra, "DROP COLUMN %s;\n",
 6045 bruce@momjian.us        17525                 :             84 :                                       fmtId(tbinfo->attnames[j]));
                              17526                 :                :                 }
                              17527                 :                :             }
  404 tgl@sss.pgh.pa.us       17528         [ +  + ]:            798 :             if (!firstitem)
                              17529                 :                :             {
                              17530                 :             38 :                 appendPQExpBufferStr(q, ") v(dname, dlen, dalign)\n"
                              17531                 :                :                                      "WHERE attrelid = ");
                              17532                 :             38 :                 appendStringLiteralAH(q, qualrelname, fout);
                              17533                 :             38 :                 appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
                              17534                 :                :                                      "  AND attname = v.dname;\n");
                              17535                 :                :                 /* Now we can issue the actual DROP COLUMN commands */
                              17536                 :             38 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17537                 :                :             }
                              17538                 :                : 
                              17539                 :                :             /*
                              17540                 :                :              * Fix up inherited columns.  As above, do the pg_attribute
                              17541                 :                :              * manipulations in a single SQL command.
                              17542                 :                :              */
                              17543                 :            798 :             firstitem = true;
                              17544         [ +  + ]:           3912 :             for (j = 0; j < tbinfo->numatts; j++)
                              17545                 :                :             {
                              17546         [ +  + ]:           3114 :                 if (!tbinfo->attisdropped[j] &&
                              17547         [ +  + ]:           3030 :                     !tbinfo->attislocal[j])
                              17548                 :                :                 {
                              17549         [ +  + ]:            603 :                     if (firstitem)
                              17550                 :                :                     {
                              17551                 :            266 :                         appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited columns.\n");
                              17552                 :            266 :                         appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
                              17553                 :                :                                              "SET attislocal = false\n"
                              17554                 :                :                                              "WHERE attrelid = ");
                              17555                 :            266 :                         appendStringLiteralAH(q, qualrelname, fout);
                              17556                 :            266 :                         appendPQExpBufferStr(q, "::pg_catalog.regclass\n"
                              17557                 :                :                                              "  AND attname IN (");
                              17558                 :            266 :                         firstitem = false;
                              17559                 :                :                     }
                              17560                 :                :                     else
                              17561                 :            337 :                         appendPQExpBufferStr(q, ", ");
 5910                         17562                 :            603 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
                              17563                 :                :                 }
                              17564                 :                :             }
  404                         17565         [ +  + ]:            798 :             if (!firstitem)
                              17566                 :            266 :                 appendPQExpBufferStr(q, ");\n");
                              17567                 :                : 
                              17568                 :                :             /*
                              17569                 :                :              * Fix up not-null constraints that come from inheritance.  As
                              17570                 :                :              * above, do the pg_constraint manipulations in a single SQL
                              17571                 :                :              * command.  (Actually, two in special cases, if we're doing an
                              17572                 :                :              * upgrade from < 18).
                              17573                 :                :              */
  302 alvherre@alvh.no-ip.    17574                 :            798 :             firstitem = true;
                              17575                 :            798 :             firstitem_extra = true;
                              17576                 :            798 :             resetPQExpBuffer(extra);
                              17577         [ +  + ]:           3912 :             for (j = 0; j < tbinfo->numatts; j++)
                              17578                 :                :             {
                              17579                 :                :                 /*
                              17580                 :                :                  * If a not-null constraint comes from inheritance, reset
                              17581                 :                :                  * conislocal.  The inhcount is fixed by ALTER TABLE INHERIT,
                              17582                 :                :                  * below.  Special hack: in versions < 18, columns with no
                              17583                 :                :                  * local definition need their constraint to be matched by
                              17584                 :                :                  * column number in conkeys instead of by constraint name,
                              17585                 :                :                  * because the latter is not available.  (We distinguish the
                              17586                 :                :                  * case because the constraint name is the empty string.)
                              17587                 :                :                  */
                              17588         [ +  + ]:           3114 :                 if (tbinfo->notnull_constrs[j] != NULL &&
                              17589         [ +  + ]:            290 :                     !tbinfo->notnull_islocal[j])
                              17590                 :                :                 {
                              17591         [ +  + ]:             84 :                     if (tbinfo->notnull_constrs[j][0] != '\0')
                              17592                 :                :                     {
                              17593         [ +  + ]:             71 :                         if (firstitem)
                              17594                 :                :                         {
                              17595                 :             61 :                             appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
                              17596                 :                :                                                  "SET conislocal = false\n"
                              17597                 :                :                                                  "WHERE contype = 'n' AND conrelid = ");
                              17598                 :             61 :                             appendStringLiteralAH(q, qualrelname, fout);
                              17599                 :             61 :                             appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
                              17600                 :                :                                                  "conname IN (");
                              17601                 :             61 :                             firstitem = false;
                              17602                 :                :                         }
                              17603                 :                :                         else
                              17604                 :             10 :                             appendPQExpBufferStr(q, ", ");
                              17605                 :             71 :                         appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
                              17606                 :                :                     }
                              17607                 :                :                     else
                              17608                 :                :                     {
                              17609         [ +  - ]:             13 :                         if (firstitem_extra)
                              17610                 :                :                         {
                              17611                 :             13 :                             appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
                              17612                 :                :                                                  "SET conislocal = false\n"
                              17613                 :                :                                                  "WHERE contype = 'n' AND conrelid = ");
                              17614                 :             13 :                             appendStringLiteralAH(extra, qualrelname, fout);
                              17615                 :             13 :                             appendPQExpBufferStr(extra, "::pg_catalog.regclass AND\n"
                              17616                 :                :                                                  "conkey IN (");
                              17617                 :             13 :                             firstitem_extra = false;
                              17618                 :                :                         }
                              17619                 :                :                         else
  302 alvherre@alvh.no-ip.    17620                 :UBC           0 :                             appendPQExpBufferStr(extra, ", ");
  302 alvherre@alvh.no-ip.    17621                 :CBC          13 :                         appendPQExpBuffer(extra, "'{%d}'", j + 1);
                              17622                 :                :                     }
                              17623                 :                :                 }
                              17624                 :                :             }
                              17625         [ +  + ]:            798 :             if (!firstitem)
                              17626                 :             61 :                 appendPQExpBufferStr(q, ");\n");
                              17627         [ +  + ]:            798 :             if (!firstitem_extra)
                              17628                 :             13 :                 appendPQExpBufferStr(extra, ");\n");
                              17629                 :                : 
                              17630         [ +  + ]:            798 :             if (extra->len > 0)
                              17631                 :             13 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17632                 :                : 
                              17633                 :                :             /*
                              17634                 :                :              * Add inherited CHECK constraints, if any.
                              17635                 :                :              *
                              17636                 :                :              * For partitions, they were already dumped, and conislocal
                              17637                 :                :              * doesn't need fixing.
                              17638                 :                :              *
                              17639                 :                :              * As above, issue only one direct manipulation of pg_constraint.
                              17640                 :                :              * Although it is tempting to merge the ALTER ADD CONSTRAINT
                              17641                 :                :              * commands into one as well, refrain for now due to concern about
                              17642                 :                :              * possible backend memory bloat if there are many such
                              17643                 :                :              * constraints.
                              17644                 :                :              */
  404 tgl@sss.pgh.pa.us       17645                 :            798 :             resetPQExpBuffer(extra);
                              17646                 :            798 :             firstitem = true;
 5910                         17647         [ +  + ]:            862 :             for (k = 0; k < tbinfo->ncheck; k++)
                              17648                 :                :             {
                              17649                 :             64 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
                              17650                 :                : 
 2280 alvherre@alvh.no-ip.    17651   [ +  +  +  +  :             64 :                 if (constr->separate || constr->conislocal || tbinfo->ispartition)
                                              +  + ]
 5910 tgl@sss.pgh.pa.us       17652                 :             62 :                     continue;
                              17653                 :                : 
  404                         17654         [ +  - ]:              2 :                 if (firstitem)
                              17655                 :              2 :                     appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraints.\n");
 1996 alvherre@alvh.no-ip.    17656                 :              2 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
                              17657                 :                :                                   foreign, qualrelname,
                              17658                 :              2 :                                   fmtId(constr->dobj.name),
                              17659                 :                :                                   constr->condef);
                              17660                 :                :                 /* Update pg_constraint after all the ALTER TABLEs */
  404 tgl@sss.pgh.pa.us       17661         [ +  - ]:              2 :                 if (firstitem)
                              17662                 :                :                 {
                              17663                 :              2 :                     appendPQExpBufferStr(extra, "UPDATE pg_catalog.pg_constraint\n"
                              17664                 :                :                                          "SET conislocal = false\n"
                              17665                 :                :                                          "WHERE contype = 'c' AND conrelid = ");
                              17666                 :              2 :                     appendStringLiteralAH(extra, qualrelname, fout);
                              17667                 :              2 :                     appendPQExpBufferStr(extra, "::pg_catalog.regclass\n");
                              17668                 :              2 :                     appendPQExpBufferStr(extra, "  AND conname IN (");
                              17669                 :              2 :                     firstitem = false;
                              17670                 :                :                 }
                              17671                 :                :                 else
  404 tgl@sss.pgh.pa.us       17672                 :UBC           0 :                     appendPQExpBufferStr(extra, ", ");
  404 tgl@sss.pgh.pa.us       17673                 :CBC           2 :                 appendStringLiteralAH(extra, constr->dobj.name, fout);
                              17674                 :                :             }
                              17675         [ +  + ]:            798 :             if (!firstitem)
                              17676                 :                :             {
                              17677                 :              2 :                 appendPQExpBufferStr(extra, ");\n");
                              17678                 :              2 :                 appendBinaryPQExpBuffer(q, extra->data, extra->len);
                              17679                 :                :             }
                              17680                 :                : 
 2280 alvherre@alvh.no-ip.    17681   [ +  +  +  + ]:            798 :             if (numParents > 0 && !tbinfo->ispartition)
                              17682                 :                :             {
                              17683                 :             63 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
 5910 tgl@sss.pgh.pa.us       17684         [ +  + ]:            137 :                 for (k = 0; k < numParents; k++)
                              17685                 :                :                 {
                              17686                 :             74 :                     TableInfo  *parentRel = parents[k];
                              17687                 :                : 
 1996 alvherre@alvh.no-ip.    17688                 :             74 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
                              17689                 :                :                                       qualrelname,
 2280                         17690                 :             74 :                                       fmtQualifiedDumpable(parentRel));
                              17691                 :                :                 }
                              17692                 :                :             }
                              17693                 :                : 
 1370 tgl@sss.pgh.pa.us       17694         [ +  + ]:            798 :             if (OidIsValid(tbinfo->reloftype))
                              17695                 :                :             {
 4310 heikki.linnakangas@i    17696                 :              6 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
 5246 peter_e@gmx.net         17697                 :              6 :                 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
                              17698                 :                :                                   qualrelname,
 1370 tgl@sss.pgh.pa.us       17699                 :              6 :                                   getFormattedTypeName(fout, tbinfo->reloftype,
                              17700                 :                :                                                        zeroIsError));
                              17701                 :                :             }
                              17702                 :                :         }
                              17703                 :                : 
                              17704                 :                :         /*
                              17705                 :                :          * In binary_upgrade mode, arrange to restore the old relfrozenxid and
                              17706                 :                :          * relminmxid of all vacuumable relations.  (While vacuum.c processes
                              17707                 :                :          * TOAST tables semi-independently, here we see them only as children
                              17708                 :                :          * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
                              17709                 :                :          * child toast table is handled below.)
                              17710                 :                :          */
 2754                         17711         [ +  + ]:           6060 :         if (dopt->binary_upgrade &&
                              17712         [ +  + ]:            816 :             (tbinfo->relkind == RELKIND_RELATION ||
                              17713         [ +  + ]:            110 :              tbinfo->relkind == RELKIND_MATVIEW))
                              17714                 :                :         {
 4084 bruce@momjian.us        17715                 :            724 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
 5910 tgl@sss.pgh.pa.us       17716                 :            724 :             appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              17717                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              17718                 :                :                               "WHERE oid = ",
 4084 bruce@momjian.us        17719                 :            724 :                               tbinfo->frozenxid, tbinfo->minmxid);
 2749 tgl@sss.pgh.pa.us       17720                 :            724 :             appendStringLiteralAH(q, qualrelname, fout);
 4310 heikki.linnakangas@i    17721                 :            724 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              17722                 :                : 
 5265 bruce@momjian.us        17723         [ +  + ]:            724 :             if (tbinfo->toast_oid)
                              17724                 :                :             {
                              17725                 :                :                 /*
                              17726                 :                :                  * The toast table will have the same OID at restore, so we
                              17727                 :                :                  * can safely target it by OID.
                              17728                 :                :                  */
 4084                         17729                 :            280 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
 5265                         17730                 :            280 :                 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              17731                 :                :                                   "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              17732                 :                :                                   "WHERE oid = '%u';\n",
 4084                         17733                 :            280 :                                   tbinfo->toast_frozenxid,
                              17734                 :            280 :                                   tbinfo->toast_minmxid, tbinfo->toast_oid);
                              17735                 :                :             }
                              17736                 :                :         }
                              17737                 :                : 
                              17738                 :                :         /*
                              17739                 :                :          * In binary_upgrade mode, restore matviews' populated status by
                              17740                 :                :          * poking pg_class directly.  This is pretty ugly, but we can't use
                              17741                 :                :          * REFRESH MATERIALIZED VIEW since it's possible that some underlying
                              17742                 :                :          * matview is not populated even though this matview is; in any case,
                              17743                 :                :          * we want to transfer the matview's heap storage, not run REFRESH.
                              17744                 :                :          */
 3980 alvherre@alvh.no-ip.    17745   [ +  +  +  + ]:           6060 :         if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
 4506 tgl@sss.pgh.pa.us       17746         [ +  + ]:             18 :             tbinfo->relispopulated)
                              17747                 :                :         {
 4310 heikki.linnakangas@i    17748                 :             16 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
                              17749                 :             16 :             appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
                              17750                 :                :                                  "SET relispopulated = 't'\n"
                              17751                 :                :                                  "WHERE oid = ");
 2749 tgl@sss.pgh.pa.us       17752                 :             16 :             appendStringLiteralAH(q, qualrelname, fout);
 4310 heikki.linnakangas@i    17753                 :             16 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              17754                 :                :         }
                              17755                 :                : 
                              17756                 :                :         /*
                              17757                 :                :          * Dump additional per-column properties that we can't handle in the
                              17758                 :                :          * main CREATE TABLE command.
                              17759                 :                :          */
 8403 bruce@momjian.us        17760         [ +  + ]:          26911 :         for (j = 0; j < tbinfo->numatts; j++)
                              17761                 :                :         {
                              17762                 :                :             /* None of this applies to dropped columns */
 4957 tgl@sss.pgh.pa.us       17763         [ +  + ]:          20851 :             if (tbinfo->attisdropped[j])
                              17764                 :            453 :                 continue;
                              17765                 :                : 
                              17766                 :                :             /*
                              17767                 :                :              * Dump per-column statistics information. We only issue an ALTER
                              17768                 :                :              * TABLE statement if the attstattarget entry for this column is
                              17769                 :                :              * not the default value.
                              17770                 :                :              */
                              17771         [ +  + ]:          20398 :             if (tbinfo->attstattarget[j] >= 0)
 1996 alvherre@alvh.no-ip.    17772                 :             38 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
                              17773                 :                :                                   foreign, qualrelname,
                              17774                 :             38 :                                   fmtId(tbinfo->attnames[j]),
 8438 tgl@sss.pgh.pa.us       17775                 :             38 :                                   tbinfo->attstattarget[j]);
                              17776                 :                : 
                              17777                 :                :             /*
                              17778                 :                :              * Dump per-column storage information.  The statement is only
                              17779                 :                :              * dumped if the storage has been changed from the type's default.
                              17780                 :                :              */
 4957                         17781         [ +  + ]:          20398 :             if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
                              17782                 :                :             {
 8069 bruce@momjian.us        17783   [ +  +  -  +  :             91 :                 switch (tbinfo->attstorage[j])
                                                 - ]
                              17784                 :                :                 {
 2012 tgl@sss.pgh.pa.us       17785                 :             10 :                     case TYPSTORAGE_PLAIN:
 8206 bruce@momjian.us        17786                 :             10 :                         storage = "PLAIN";
                              17787                 :             10 :                         break;
 2012 tgl@sss.pgh.pa.us       17788                 :             43 :                     case TYPSTORAGE_EXTERNAL:
 8206 bruce@momjian.us        17789                 :             43 :                         storage = "EXTERNAL";
                              17790                 :             43 :                         break;
 2012 tgl@sss.pgh.pa.us       17791                 :UBC           0 :                     case TYPSTORAGE_EXTENDED:
 8206 bruce@momjian.us        17792                 :              0 :                         storage = "EXTENDED";
                              17793                 :              0 :                         break;
 2012 tgl@sss.pgh.pa.us       17794                 :CBC          38 :                     case TYPSTORAGE_MAIN:
                              17795                 :             38 :                         storage = "MAIN";
                              17796                 :             38 :                         break;
 8206 bruce@momjian.us        17797                 :UBC           0 :                     default:
                              17798                 :              0 :                         storage = NULL;
                              17799                 :                :                 }
                              17800                 :                : 
                              17801                 :                :                 /*
                              17802                 :                :                  * Only dump the statement if it's a storage type we recognize
                              17803                 :                :                  */
 8069 bruce@momjian.us        17804         [ +  - ]:CBC          91 :                 if (storage != NULL)
 1996 alvherre@alvh.no-ip.    17805                 :             91 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
                              17806                 :                :                                       foreign, qualrelname,
                              17807                 :             91 :                                       fmtId(tbinfo->attnames[j]),
                              17808                 :                :                                       storage);
                              17809                 :                :             }
                              17810                 :                : 
                              17811                 :                :             /*
                              17812                 :                :              * Dump per-column compression, if it's been set.
                              17813                 :                :              */
 1631 tgl@sss.pgh.pa.us       17814         [ +  + ]:          20398 :             if (!dopt->no_toast_compression)
                              17815                 :                :             {
                              17816                 :                :                 const char *cmname;
                              17817                 :                : 
                              17818      [ +  +  + ]:          20300 :                 switch (tbinfo->attcompression[j])
                              17819                 :                :                 {
                              17820                 :             77 :                     case 'p':
                              17821                 :             77 :                         cmname = "pglz";
                              17822                 :             77 :                         break;
                              17823                 :             99 :                     case 'l':
                              17824                 :             99 :                         cmname = "lz4";
                              17825                 :             99 :                         break;
                              17826                 :          20124 :                     default:
                              17827                 :          20124 :                         cmname = NULL;
                              17828                 :          20124 :                         break;
                              17829                 :                :                 }
                              17830                 :                : 
 1563                         17831         [ +  + ]:          20300 :                 if (cmname != NULL)
 1631                         17832                 :            176 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
                              17833                 :                :                                       foreign, qualrelname,
                              17834                 :            176 :                                       fmtId(tbinfo->attnames[j]),
                              17835                 :                :                                       cmname);
                              17836                 :                :             }
                              17837                 :                : 
                              17838                 :                :             /*
                              17839                 :                :              * Dump per-column attributes.
                              17840                 :                :              */
 1563                         17841         [ +  + ]:          20398 :             if (tbinfo->attoptions[j][0] != '\0')
                              17842                 :             38 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
                              17843                 :                :                                   foreign, qualrelname,
                              17844                 :             38 :                                   fmtId(tbinfo->attnames[j]),
                              17845                 :             38 :                                   tbinfo->attoptions[j]);
                              17846                 :                : 
                              17847                 :                :             /*
                              17848                 :                :              * Dump per-column fdw options.
                              17849                 :                :              */
                              17850         [ +  + ]:          20398 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                              17851         [ +  + ]:             40 :                 tbinfo->attfdwoptions[j][0] != '\0')
                              17852                 :             38 :                 appendPQExpBuffer(q,
                              17853                 :                :                                   "ALTER FOREIGN TABLE ONLY %s ALTER COLUMN %s OPTIONS (\n"
                              17854                 :                :                                   "    %s\n"
                              17855                 :                :                                   ");\n",
                              17856                 :                :                                   qualrelname,
                              17857                 :             38 :                                   fmtId(tbinfo->attnames[j]),
                              17858                 :             38 :                                   tbinfo->attfdwoptions[j]);
                              17859                 :                :         }                       /* end loop over columns */
                              17860                 :                : 
 1178 peter@eisentraut.org    17861                 :           6060 :         free(partkeydef);
                              17862                 :           6060 :         free(ftoptions);
                              17863                 :           6060 :         free(srvname);
                              17864                 :                :     }
                              17865                 :                : 
                              17866                 :                :     /*
                              17867                 :                :      * dump properties we only have ALTER TABLE syntax for
                              17868                 :                :      */
 3821 tgl@sss.pgh.pa.us       17869         [ +  + ]:           6596 :     if ((tbinfo->relkind == RELKIND_RELATION ||
 3195 rhaas@postgresql.org    17870         [ +  + ]:           1586 :          tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
 3821 tgl@sss.pgh.pa.us       17871         [ +  + ]:            996 :          tbinfo->relkind == RELKIND_MATVIEW) &&
 4318 peter_e@gmx.net         17872         [ +  + ]:           6020 :         tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
                              17873                 :                :     {
 4320 rhaas@postgresql.org    17874         [ +  - ]:            192 :         if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
                              17875                 :                :         {
                              17876                 :                :             /* nothing to do, will be set when the index is dumped */
                              17877                 :                :         }
                              17878         [ +  - ]:            192 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
                              17879                 :                :         {
                              17880                 :            192 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
                              17881                 :                :                               qualrelname);
                              17882                 :                :         }
 4320 rhaas@postgresql.org    17883         [ #  # ]:UBC           0 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
                              17884                 :                :         {
                              17885                 :              0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
                              17886                 :                :                               qualrelname);
                              17887                 :                :         }
                              17888                 :                :     }
                              17889                 :                : 
 3625 sfrost@snowman.net      17890         [ +  + ]:CBC        6596 :     if (tbinfo->forcerowsec)
                              17891                 :              5 :         appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
                              17892                 :                :                           qualrelname);
                              17893                 :                : 
 3980 alvherre@alvh.no-ip.    17894         [ +  + ]:           6596 :     if (dopt->binary_upgrade)
 2749 tgl@sss.pgh.pa.us       17895                 :            868 :         binary_upgrade_extension_member(q, &tbinfo->dobj,
                              17896                 :                :                                         reltypename, qrelname,
                              17897                 :            868 :                                         tbinfo->dobj.namespace->dobj.name);
                              17898                 :                : 
 3440 sfrost@snowman.net      17899         [ +  - ]:           6596 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17900                 :                :     {
 1373 peter@eisentraut.org    17901                 :           6596 :         char       *tablespace = NULL;
 2299 tgl@sss.pgh.pa.us       17902                 :           6596 :         char       *tableam = NULL;
                              17903                 :                : 
                              17904                 :                :         /*
                              17905                 :                :          * _selectTablespace() relies on tablespace-enabled objects in the
                              17906                 :                :          * default tablespace to have a tablespace of "" (empty string) versus
                              17907                 :                :          * non-tablespace-enabled objects to have a tablespace of NULL.
                              17908                 :                :          * getTables() sets tbinfo->reltablespace to "" for the default
                              17909                 :                :          * tablespace (not NULL).
                              17910                 :                :          */
 1373 peter@eisentraut.org    17911   [ +  +  +  -  :           6596 :         if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
                                     +  -  +  -  +  
                                     +  +  +  -  +  
                                              +  - ]
                              17912                 :           6020 :             tablespace = tbinfo->reltablespace;
                              17913                 :                : 
  530 alvherre@alvh.no-ip.    17914   [ +  +  +  -  :           6596 :         if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
                                              +  + ]
                              17915         [ +  + ]:           1166 :             tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 2376 andres@anarazel.de      17916                 :           6020 :             tableam = tbinfo->amname;
                              17917                 :                : 
 3440 sfrost@snowman.net      17918                 :           6596 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    17919         [ +  + ]:           6596 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              17920                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              17921                 :                :                                   .tablespace = tablespace,
                              17922                 :                :                                   .tableam = tableam,
                              17923                 :                :                                   .relkind = tbinfo->relkind,
                              17924                 :                :                                   .owner = tbinfo->rolname,
                              17925                 :                :                                   .description = reltypename,
                              17926                 :                :                                   .section = tbinfo->postponed_def ?
                              17927                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              17928                 :                :                                   .createStmt = q->data,
                              17929                 :                :                                   .dropStmt = delq->data));
                              17930                 :                :     }
                              17931                 :                : 
                              17932                 :                :     /* Dump Table Comments */
 3440 sfrost@snowman.net      17933         [ +  + ]:           6596 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              17934                 :             86 :         dumpTableComment(fout, tbinfo, reltypename);
                              17935                 :                : 
                              17936                 :                :     /* Dump Table Security Labels */
                              17937         [ -  + ]:           6596 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 3440 sfrost@snowman.net      17938                 :UBC           0 :         dumpTableSecLabel(fout, tbinfo, reltypename);
                              17939                 :                : 
                              17940                 :                :     /*
                              17941                 :                :      * Dump comments for not-null constraints that aren't to be dumped
                              17942                 :                :      * separately (those are processed by collectComments/dumpComment).
                              17943                 :                :      */
   72 alvherre@kurilemu.de    17944   [ +  -  +  - ]:CBC        6596 :     if (!fout->dopt->no_comments && dopt->dumpSchema &&
                              17945         [ +  - ]:           6596 :         fout->remoteVersion >= 180000)
                              17946                 :                :     {
                              17947                 :           6596 :         PQExpBuffer comment = NULL;
                              17948                 :           6596 :         PQExpBuffer tag = NULL;
                              17949                 :                : 
                              17950         [ +  + ]:          30801 :         for (j = 0; j < tbinfo->numatts; j++)
                              17951                 :                :         {
                              17952         [ +  + ]:          24205 :             if (tbinfo->notnull_constrs[j] != NULL &&
                              17953         [ +  + ]:           2537 :                 tbinfo->notnull_comment[j] != NULL)
                              17954                 :                :             {
                              17955         [ +  - ]:             48 :                 if (comment == NULL)
                              17956                 :                :                 {
                              17957                 :             48 :                     comment = createPQExpBuffer();
                              17958                 :             48 :                     tag = createPQExpBuffer();
                              17959                 :                :                 }
                              17960                 :                :                 else
                              17961                 :                :                 {
   72 alvherre@kurilemu.de    17962                 :UBC           0 :                     resetPQExpBuffer(comment);
                              17963                 :              0 :                     resetPQExpBuffer(tag);
                              17964                 :                :                 }
                              17965                 :                : 
   72 alvherre@kurilemu.de    17966                 :CBC          48 :                 appendPQExpBuffer(comment, "COMMENT ON CONSTRAINT %s ON %s IS ",
                              17967                 :             48 :                                   fmtId(tbinfo->notnull_constrs[j]), qualrelname);
                              17968                 :             48 :                 appendStringLiteralAH(comment, tbinfo->notnull_comment[j], fout);
                              17969                 :             48 :                 appendPQExpBufferStr(comment, ";\n");
                              17970                 :                : 
                              17971                 :             48 :                 appendPQExpBuffer(tag, "CONSTRAINT %s ON %s",
                              17972                 :             48 :                                   fmtId(tbinfo->notnull_constrs[j]), qrelname);
                              17973                 :                : 
                              17974                 :             48 :                 ArchiveEntry(fout, nilCatalogId, createDumpId(),
                              17975                 :             48 :                              ARCHIVE_OPTS(.tag = tag->data,
                              17976                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              17977                 :                :                                           .owner = tbinfo->rolname,
                              17978                 :                :                                           .description = "COMMENT",
                              17979                 :                :                                           .section = SECTION_NONE,
                              17980                 :                :                                           .createStmt = comment->data,
                              17981                 :                :                                           .deps = &(tbinfo->dobj.dumpId),
                              17982                 :                :                                           .nDeps = 1));
                              17983                 :                :             }
                              17984                 :                :         }
                              17985                 :                : 
                              17986                 :           6596 :         destroyPQExpBuffer(comment);
                              17987                 :           6596 :         destroyPQExpBuffer(tag);
                              17988                 :                :     }
                              17989                 :                : 
                              17990                 :                :     /* Dump comments on inlined table constraints */
 7571 tgl@sss.pgh.pa.us       17991         [ +  + ]:           7239 :     for (j = 0; j < tbinfo->ncheck; j++)
                              17992                 :                :     {
                              17993                 :            643 :         ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              17994                 :                : 
 6329                         17995   [ +  +  +  + ]:            643 :         if (constr->separate || !constr->conislocal)
 7571                         17996                 :            274 :             continue;
                              17997                 :                : 
 1039                         17998         [ +  + ]:            369 :         if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
 3440 sfrost@snowman.net      17999                 :             43 :             dumpTableConstraintComment(fout, constr);
                              18000                 :                :     }
                              18001                 :                : 
 8520 tgl@sss.pgh.pa.us       18002                 :           6596 :     destroyPQExpBuffer(q);
                              18003                 :           6596 :     destroyPQExpBuffer(delq);
  404                         18004                 :           6596 :     destroyPQExpBuffer(extra);
 2749                         18005                 :           6596 :     free(qrelname);
                              18006                 :           6596 :     free(qualrelname);
 9003 pjw@rhyme.com.au        18007                 :           6596 : }
                              18008                 :                : 
                              18009                 :                : /*
                              18010                 :                :  * dumpTableAttach
                              18011                 :                :  *    write to fout the commands to attach a child partition
                              18012                 :                :  *
                              18013                 :                :  * Child partitions are always made by creating them separately
                              18014                 :                :  * and then using ATTACH PARTITION, rather than using
                              18015                 :                :  * CREATE TABLE ... PARTITION OF.  This is important for preserving
                              18016                 :                :  * any possible discrepancy in column layout, to allow assigning the
                              18017                 :                :  * correct tablespace if different, and so that it's possible to restore
                              18018                 :                :  * a partition without restoring its parent.  (You'll get an error from
                              18019                 :                :  * the ATTACH PARTITION command, but that can be ignored, or skipped
                              18020                 :                :  * using "pg_restore -L" if you prefer.)  The last point motivates
                              18021                 :                :  * treating ATTACH PARTITION as a completely separate ArchiveEntry
                              18022                 :                :  * rather than emitting it within the child partition's ArchiveEntry.
                              18023                 :                :  */
                              18024                 :                : static void
 1669 peter@eisentraut.org    18025                 :           1435 : dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
                              18026                 :                : {
 1699 tgl@sss.pgh.pa.us       18027                 :           1435 :     DumpOptions *dopt = fout->dopt;
                              18028                 :                :     PQExpBuffer q;
                              18029                 :                :     PGresult   *res;
                              18030                 :                :     char       *partbound;
                              18031                 :                : 
                              18032                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18033         [ +  + ]:           1435 :     if (!dopt->dumpSchema)
 1699 tgl@sss.pgh.pa.us       18034                 :             54 :         return;
                              18035                 :                : 
                              18036                 :           1381 :     q = createPQExpBuffer();
                              18037                 :                : 
 1370                         18038         [ +  + ]:           1381 :     if (!fout->is_prepared[PREPQUERY_DUMPTABLEATTACH])
                              18039                 :                :     {
                              18040                 :                :         /* Set up query for partbound details */
                              18041                 :             49 :         appendPQExpBufferStr(q,
                              18042                 :                :                              "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
                              18043                 :                : 
                              18044                 :             49 :         appendPQExpBufferStr(q,
                              18045                 :                :                              "SELECT pg_get_expr(c.relpartbound, c.oid) "
                              18046                 :                :                              "FROM pg_class c "
                              18047                 :                :                              "WHERE c.oid = $1");
                              18048                 :                : 
                              18049                 :             49 :         ExecuteSqlStatement(fout, q->data);
                              18050                 :                : 
                              18051                 :             49 :         fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
                              18052                 :                :     }
                              18053                 :                : 
                              18054                 :           1381 :     printfPQExpBuffer(q,
                              18055                 :                :                       "EXECUTE dumpTableAttach('%u')",
                              18056                 :           1381 :                       attachinfo->partitionTbl->dobj.catId.oid);
                              18057                 :                : 
                              18058                 :           1381 :     res = ExecuteSqlQueryForSingleRow(fout, q->data);
                              18059                 :           1381 :     partbound = PQgetvalue(res, 0, 0);
                              18060                 :                : 
                              18061                 :                :     /* Perform ALTER TABLE on the parent */
                              18062                 :           1381 :     printfPQExpBuffer(q,
                              18063                 :                :                       "ALTER TABLE ONLY %s ",
 1699                         18064                 :           1381 :                       fmtQualifiedDumpable(attachinfo->parentTbl));
                              18065                 :           1381 :     appendPQExpBuffer(q,
                              18066                 :                :                       "ATTACH PARTITION %s %s;\n",
                              18067                 :           1381 :                       fmtQualifiedDumpable(attachinfo->partitionTbl),
                              18068                 :                :                       partbound);
                              18069                 :                : 
                              18070                 :                :     /*
                              18071                 :                :      * There is no point in creating a drop query as the drop is done by table
                              18072                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                              18073                 :                :      * Although this object doesn't really have ownership as such, set the
                              18074                 :                :      * owner field anyway to ensure that the command is run by the correct
                              18075                 :                :      * role at restore time.
                              18076                 :                :      */
                              18077                 :           1381 :     ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
                              18078                 :           1381 :                  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              18079                 :                :                               .namespace = attachinfo->dobj.namespace->dobj.name,
                              18080                 :                :                               .owner = attachinfo->partitionTbl->rolname,
                              18081                 :                :                               .description = "TABLE ATTACH",
                              18082                 :                :                               .section = SECTION_PRE_DATA,
                              18083                 :                :                               .createStmt = q->data));
                              18084                 :                : 
 1370                         18085                 :           1381 :     PQclear(res);
 1699                         18086                 :           1381 :     destroyPQExpBuffer(q);
                              18087                 :                : }
                              18088                 :                : 
                              18089                 :                : /*
                              18090                 :                :  * dumpAttrDef --- dump an attribute's default-value declaration
                              18091                 :                :  */
                              18092                 :                : static void
 1669 peter@eisentraut.org    18093                 :           1104 : dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
                              18094                 :                : {
 3524 tgl@sss.pgh.pa.us       18095                 :           1104 :     DumpOptions *dopt = fout->dopt;
 7945                         18096                 :           1104 :     TableInfo  *tbinfo = adinfo->adtable;
                              18097                 :           1104 :     int         adnum = adinfo->adnum;
                              18098                 :                :     PQExpBuffer q;
                              18099                 :                :     PQExpBuffer delq;
                              18100                 :                :     char       *qualrelname;
                              18101                 :                :     char       *tag;
                              18102                 :                :     char       *foreign;
                              18103                 :                : 
                              18104                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18105         [ -  + ]:           1104 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       18106                 :UBC           0 :         return;
                              18107                 :                : 
                              18108                 :                :     /* Skip if not "separate"; it was dumped in the table's definition */
 4957 tgl@sss.pgh.pa.us       18109         [ +  + ]:CBC        1104 :     if (!adinfo->separate)
 7945                         18110                 :            920 :         return;
                              18111                 :                : 
                              18112                 :            184 :     q = createPQExpBuffer();
                              18113                 :            184 :     delq = createPQExpBuffer();
                              18114                 :                : 
 2749                         18115                 :            184 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              18116                 :                : 
 1996 alvherre@alvh.no-ip.    18117         [ -  + ]:            184 :     foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              18118                 :                : 
                              18119                 :            184 :     appendPQExpBuffer(q,
                              18120                 :                :                       "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
                              18121                 :            184 :                       foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
 7945 tgl@sss.pgh.pa.us       18122                 :            184 :                       adinfo->adef_expr);
                              18123                 :                : 
 1996 alvherre@alvh.no-ip.    18124                 :            184 :     appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
                              18125                 :                :                       foreign, qualrelname,
 7945 tgl@sss.pgh.pa.us       18126                 :            184 :                       fmtId(tbinfo->attnames[adnum - 1]));
                              18127                 :                : 
 3481 peter_e@gmx.net         18128                 :            184 :     tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
                              18129                 :                : 
 3440 sfrost@snowman.net      18130         [ +  - ]:            184 :     if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18131                 :            184 :         ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18132                 :            184 :                      ARCHIVE_OPTS(.tag = tag,
                              18133                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              18134                 :                :                                   .owner = tbinfo->rolname,
                              18135                 :                :                                   .description = "DEFAULT",
                              18136                 :                :                                   .section = SECTION_PRE_DATA,
                              18137                 :                :                                   .createStmt = q->data,
                              18138                 :                :                                   .dropStmt = delq->data));
                              18139                 :                : 
 3481 peter_e@gmx.net         18140                 :            184 :     free(tag);
 7945 tgl@sss.pgh.pa.us       18141                 :            184 :     destroyPQExpBuffer(q);
                              18142                 :            184 :     destroyPQExpBuffer(delq);
 2749                         18143                 :            184 :     free(qualrelname);
                              18144                 :                : }
                              18145                 :                : 
                              18146                 :                : /*
                              18147                 :                :  * getAttrName: extract the correct name for an attribute
                              18148                 :                :  *
                              18149                 :                :  * The array tblInfo->attnames[] only provides names of user attributes;
                              18150                 :                :  * if a system attribute number is supplied, we have to fake it.
                              18151                 :                :  * We also do a little bit of bounds checking for safety's sake.
                              18152                 :                :  */
                              18153                 :                : static const char *
 1669 peter@eisentraut.org    18154                 :           2153 : getAttrName(int attrnum, const TableInfo *tblInfo)
                              18155                 :                : {
 8903 tgl@sss.pgh.pa.us       18156   [ +  -  +  - ]:           2153 :     if (attrnum > 0 && attrnum <= tblInfo->numatts)
 8717 bruce@momjian.us        18157                 :           2153 :         return tblInfo->attnames[attrnum - 1];
 8903 tgl@sss.pgh.pa.us       18158   [ #  #  #  #  :UBC           0 :     switch (attrnum)
                                           #  #  # ]
                              18159                 :                :     {
                              18160                 :              0 :         case SelfItemPointerAttributeNumber:
                              18161                 :              0 :             return "ctid";
                              18162                 :              0 :         case MinTransactionIdAttributeNumber:
                              18163                 :              0 :             return "xmin";
                              18164                 :              0 :         case MinCommandIdAttributeNumber:
                              18165                 :              0 :             return "cmin";
                              18166                 :              0 :         case MaxTransactionIdAttributeNumber:
                              18167                 :              0 :             return "xmax";
                              18168                 :              0 :         case MaxCommandIdAttributeNumber:
                              18169                 :              0 :             return "cmax";
                              18170                 :              0 :         case TableOidAttributeNumber:
                              18171                 :              0 :             return "tableoid";
                              18172                 :                :     }
 1247                         18173                 :              0 :     pg_fatal("invalid column number %d for table \"%s\"",
                              18174                 :                :              attrnum, tblInfo->dobj.name);
                              18175                 :                :     return NULL;                /* keep compiler quiet */
                              18176                 :                : }
                              18177                 :                : 
                              18178                 :                : /*
                              18179                 :                :  * dumpIndex
                              18180                 :                :  *    write out to fout a user-defined index
                              18181                 :                :  */
                              18182                 :                : static void
 1669 peter@eisentraut.org    18183                 :CBC        2688 : dumpIndex(Archive *fout, const IndxInfo *indxinfo)
                              18184                 :                : {
 3524 tgl@sss.pgh.pa.us       18185                 :           2688 :     DumpOptions *dopt = fout->dopt;
 7945                         18186                 :           2688 :     TableInfo  *tbinfo = indxinfo->indextable;
 4454                         18187                 :           2688 :     bool        is_constraint = (indxinfo->indexconstraint != 0);
                              18188                 :                :     PQExpBuffer q;
                              18189                 :                :     PQExpBuffer delq;
                              18190                 :                :     char       *qindxname;
                              18191                 :                :     char       *qqindxname;
                              18192                 :                : 
                              18193                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18194         [ +  + ]:           2688 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       18195                 :            117 :         return;
                              18196                 :                : 
                              18197                 :           2571 :     q = createPQExpBuffer();
                              18198                 :           2571 :     delq = createPQExpBuffer();
                              18199                 :                : 
 2749                         18200                 :           2571 :     qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
 2005 alvherre@alvh.no-ip.    18201                 :           2571 :     qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
                              18202                 :                : 
                              18203                 :                :     /*
                              18204                 :                :      * If there's an associated constraint, don't dump the index per se, but
                              18205                 :                :      * do dump any comment for it.  (This is safe because dependency ordering
                              18206                 :                :      * will have ensured the constraint is emitted first.)  Note that the
                              18207                 :                :      * emitted comment has to be shown as depending on the constraint, not the
                              18208                 :                :      * index, in such cases.
                              18209                 :                :      */
 4454 tgl@sss.pgh.pa.us       18210         [ +  + ]:           2571 :     if (!is_constraint)
                              18211                 :                :     {
 2454 michael@paquier.xyz     18212                 :           1077 :         char       *indstatcols = indxinfo->indstatcols;
                              18213                 :           1077 :         char       *indstatvals = indxinfo->indstatvals;
                              18214                 :           1077 :         char      **indstatcolsarray = NULL;
                              18215                 :           1077 :         char      **indstatvalsarray = NULL;
 1752                         18216                 :           1077 :         int         nstatcols = 0;
                              18217                 :           1077 :         int         nstatvals = 0;
                              18218                 :                : 
 3980 alvherre@alvh.no-ip.    18219         [ +  + ]:           1077 :         if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    18220                 :            156 :             binary_upgrade_set_pg_class_oids(fout, q,
  430 nathan@postgresql.or    18221                 :            156 :                                              indxinfo->dobj.catId.oid);
                              18222                 :                : 
                              18223                 :                :         /* Plain secondary index */
 7945 tgl@sss.pgh.pa.us       18224                 :           1077 :         appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
                              18225                 :                : 
                              18226                 :                :         /*
                              18227                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              18228                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              18229                 :                :          * similar code in dumpConstraint!
                              18230                 :                :          */
                              18231                 :                : 
                              18232                 :                :         /* If the index is clustered, we need to record that. */
                              18233         [ -  + ]:           1077 :         if (indxinfo->indisclustered)
                              18234                 :                :         {
 7945 tgl@sss.pgh.pa.us       18235                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2749                         18236                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18237                 :                :             /* index name is not qualified in this syntax */
 7945                         18238                 :              0 :             appendPQExpBuffer(q, " ON %s;\n",
                              18239                 :                :                               qindxname);
                              18240                 :                :         }
                              18241                 :                : 
                              18242                 :                :         /*
                              18243                 :                :          * If the index has any statistics on some of its columns, generate
                              18244                 :                :          * the associated ALTER INDEX queries.
                              18245                 :                :          */
 1752 michael@paquier.xyz     18246   [ +  +  -  + ]:CBC        1077 :         if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
                              18247                 :                :         {
                              18248                 :                :             int         j;
                              18249                 :                : 
                              18250         [ -  + ]:             38 :             if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
 1247 tgl@sss.pgh.pa.us       18251                 :UBC           0 :                 pg_fatal("could not parse index statistic columns");
 1752 michael@paquier.xyz     18252         [ -  + ]:CBC          38 :             if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
 1247 tgl@sss.pgh.pa.us       18253                 :UBC           0 :                 pg_fatal("could not parse index statistic values");
 1752 michael@paquier.xyz     18254         [ -  + ]:CBC          38 :             if (nstatcols != nstatvals)
 1247 tgl@sss.pgh.pa.us       18255                 :UBC           0 :                 pg_fatal("mismatched number of columns and values for index statistics");
                              18256                 :                : 
 2454 michael@paquier.xyz     18257         [ +  + ]:CBC         114 :             for (j = 0; j < nstatcols; j++)
                              18258                 :                :             {
 2005 alvherre@alvh.no-ip.    18259                 :             76 :                 appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
                              18260                 :                : 
                              18261                 :                :                 /*
                              18262                 :                :                  * Note that this is a column number, so no quotes should be
                              18263                 :                :                  * used.
                              18264                 :                :                  */
 2454 michael@paquier.xyz     18265                 :             76 :                 appendPQExpBuffer(q, "ALTER COLUMN %s ",
                              18266                 :             76 :                                   indstatcolsarray[j]);
                              18267                 :             76 :                 appendPQExpBuffer(q, "SET STATISTICS %s;\n",
                              18268                 :             76 :                                   indstatvalsarray[j]);
                              18269                 :                :             }
                              18270                 :                :         }
                              18271                 :                : 
                              18272                 :                :         /* Indexes can depend on extensions */
 2005 alvherre@alvh.no-ip.    18273                 :           1077 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              18274                 :                :                                     "pg_catalog.pg_class",
                              18275                 :                :                                     "INDEX", qqindxname);
                              18276                 :                : 
                              18277                 :                :         /* If the index defines identity, we need to record that. */
 4320 rhaas@postgresql.org    18278         [ -  + ]:           1077 :         if (indxinfo->indisreplident)
                              18279                 :                :         {
 4320 rhaas@postgresql.org    18280                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
 2749 tgl@sss.pgh.pa.us       18281                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18282                 :                :             /* index name is not qualified in this syntax */
 4320 rhaas@postgresql.org    18283                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              18284                 :                :                               qindxname);
                              18285                 :                :         }
                              18286                 :                : 
                              18287                 :                :         /*
                              18288                 :                :          * If this index is a member of a partitioned index, the backend will
                              18289                 :                :          * not allow us to drop it separately, so don't try.  It will go away
                              18290                 :                :          * automatically when we drop either the index's table or the
                              18291                 :                :          * partitioned index.  (If, in a selective restore with --clean, we
                              18292                 :                :          * drop neither of those, then this index will not be dropped either.
                              18293                 :                :          * But that's fine, and even if you think it's not, the backend won't
                              18294                 :                :          * let us do differently.)
                              18295                 :                :          */
  143 tgl@sss.pgh.pa.us       18296         [ +  + ]:CBC        1077 :         if (indxinfo->parentidx == 0)
                              18297                 :            871 :             appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
                              18298                 :                : 
 3440 sfrost@snowman.net      18299         [ +  - ]:           1077 :         if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18300                 :           1077 :             ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18301                 :           1077 :                          ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
                              18302                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18303                 :                :                                       .tablespace = indxinfo->tablespace,
                              18304                 :                :                                       .owner = tbinfo->rolname,
                              18305                 :                :                                       .description = "INDEX",
                              18306                 :                :                                       .section = SECTION_POST_DATA,
                              18307                 :                :                                       .createStmt = q->data,
                              18308                 :                :                                       .dropStmt = delq->data));
                              18309                 :                : 
 1178 peter@eisentraut.org    18310                 :           1077 :         free(indstatcolsarray);
                              18311                 :           1077 :         free(indstatvalsarray);
                              18312                 :                :     }
                              18313                 :                : 
                              18314                 :                :     /* Dump Index Comments */
 3440 sfrost@snowman.net      18315         [ +  + ]:           2571 :     if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       18316         [ +  + ]:             15 :         dumpComment(fout, "INDEX", qindxname,
 3440 sfrost@snowman.net      18317                 :             15 :                     tbinfo->dobj.namespace->dobj.name,
                              18318                 :                :                     tbinfo->rolname,
                              18319                 :                :                     indxinfo->dobj.catId, 0,
                              18320                 :                :                     is_constraint ? indxinfo->indexconstraint :
                              18321                 :                :                     indxinfo->dobj.dumpId);
                              18322                 :                : 
 7945 tgl@sss.pgh.pa.us       18323                 :           2571 :     destroyPQExpBuffer(q);
                              18324                 :           2571 :     destroyPQExpBuffer(delq);
 2749                         18325                 :           2571 :     free(qindxname);
 2005 alvherre@alvh.no-ip.    18326                 :           2571 :     free(qqindxname);
                              18327                 :                : }
                              18328                 :                : 
                              18329                 :                : /*
                              18330                 :                :  * dumpIndexAttach
                              18331                 :                :  *    write out to fout a partitioned-index attachment clause
                              18332                 :                :  */
                              18333                 :                : static void
 1669 peter@eisentraut.org    18334                 :            612 : dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
                              18335                 :                : {
                              18336                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18337         [ +  + ]:            612 :     if (!fout->dopt->dumpSchema)
 2787 alvherre@alvh.no-ip.    18338                 :             48 :         return;
                              18339                 :                : 
                              18340         [ +  - ]:            564 :     if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18341                 :                :     {
 2784 tgl@sss.pgh.pa.us       18342                 :            564 :         PQExpBuffer q = createPQExpBuffer();
                              18343                 :                : 
 2566                         18344                 :            564 :         appendPQExpBuffer(q, "ALTER INDEX %s ",
 2749                         18345                 :            564 :                           fmtQualifiedDumpable(attachinfo->parentIdx));
 2787 alvherre@alvh.no-ip.    18346                 :            564 :         appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
 2749 tgl@sss.pgh.pa.us       18347                 :            564 :                           fmtQualifiedDumpable(attachinfo->partitionIdx));
                              18348                 :                : 
                              18349                 :                :         /*
                              18350                 :                :          * There is no need for a dropStmt since the drop is done implicitly
                              18351                 :                :          * when we drop either the index's table or the partitioned index.
                              18352                 :                :          * Moreover, since there's no ALTER INDEX DETACH PARTITION command,
                              18353                 :                :          * there's no way to do it anyway.  (If you think to change this,
                              18354                 :                :          * consider also what to do with --if-exists.)
                              18355                 :                :          *
                              18356                 :                :          * Although this object doesn't really have ownership as such, set the
                              18357                 :                :          * owner field anyway to ensure that the command is run by the correct
                              18358                 :                :          * role at restore time.
                              18359                 :                :          */
 2787 alvherre@alvh.no-ip.    18360                 :            564 :         ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
 2409                         18361                 :            564 :                      ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              18362                 :                :                                   .namespace = attachinfo->dobj.namespace->dobj.name,
                              18363                 :                :                                   .owner = attachinfo->parentIdx->indextable->rolname,
                              18364                 :                :                                   .description = "INDEX ATTACH",
                              18365                 :                :                                   .section = SECTION_POST_DATA,
                              18366                 :                :                                   .createStmt = q->data));
                              18367                 :                : 
 2787                         18368                 :            564 :         destroyPQExpBuffer(q);
                              18369                 :                :     }
                              18370                 :                : }
                              18371                 :                : 
                              18372                 :                : /*
                              18373                 :                :  * dumpStatisticsExt
                              18374                 :                :  *    write out to fout an extended statistics object
                              18375                 :                :  */
                              18376                 :                : static void
 1669 peter@eisentraut.org    18377                 :            151 : dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
                              18378                 :                : {
 3088 alvherre@alvh.no-ip.    18379                 :            151 :     DumpOptions *dopt = fout->dopt;
                              18380                 :                :     PQExpBuffer q;
                              18381                 :                :     PQExpBuffer delq;
                              18382                 :                :     PQExpBuffer query;
                              18383                 :                :     char       *qstatsextname;
                              18384                 :                :     PGresult   *res;
                              18385                 :                :     char       *stxdef;
                              18386                 :                : 
                              18387                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18388         [ +  + ]:            151 :     if (!dopt->dumpSchema)
 3088 alvherre@alvh.no-ip.    18389                 :             18 :         return;
                              18390                 :                : 
                              18391                 :            133 :     q = createPQExpBuffer();
                              18392                 :            133 :     delq = createPQExpBuffer();
 2764 tgl@sss.pgh.pa.us       18393                 :            133 :     query = createPQExpBuffer();
                              18394                 :                : 
 2749                         18395                 :            133 :     qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
                              18396                 :                : 
 2764                         18397                 :            133 :     appendPQExpBuffer(query, "SELECT "
                              18398                 :                :                       "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
                              18399                 :            133 :                       statsextinfo->dobj.catId.oid);
                              18400                 :                : 
                              18401                 :            133 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              18402                 :                : 
                              18403                 :            133 :     stxdef = PQgetvalue(res, 0, 0);
                              18404                 :                : 
                              18405                 :                :     /* Result of pg_get_statisticsobjdef is complete except for semicolon */
                              18406                 :            133 :     appendPQExpBuffer(q, "%s;\n", stxdef);
                              18407                 :                : 
                              18408                 :                :     /*
                              18409                 :                :      * We only issue an ALTER STATISTICS statement if the stxstattarget entry
                              18410                 :                :      * for this statistics object is not the default value.
                              18411                 :                :      */
 2188 tomas.vondra@postgre    18412         [ +  + ]:            133 :     if (statsextinfo->stattarget >= 0)
                              18413                 :                :     {
                              18414                 :             38 :         appendPQExpBuffer(q, "ALTER STATISTICS %s ",
                              18415                 :             38 :                           fmtQualifiedDumpable(statsextinfo));
                              18416                 :             38 :         appendPQExpBuffer(q, "SET STATISTICS %d;\n",
                              18417                 :             38 :                           statsextinfo->stattarget);
                              18418                 :                :     }
                              18419                 :                : 
 2749 tgl@sss.pgh.pa.us       18420                 :            133 :     appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
                              18421                 :            133 :                       fmtQualifiedDumpable(statsextinfo));
                              18422                 :                : 
 3088 alvherre@alvh.no-ip.    18423         [ +  - ]:            133 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 3034 bruce@momjian.us        18424                 :            133 :         ArchiveEntry(fout, statsextinfo->dobj.catId,
                              18425                 :            133 :                      statsextinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18426                 :            133 :                      ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
                              18427                 :                :                                   .namespace = statsextinfo->dobj.namespace->dobj.name,
                              18428                 :                :                                   .owner = statsextinfo->rolname,
                              18429                 :                :                                   .description = "STATISTICS",
                              18430                 :                :                                   .section = SECTION_POST_DATA,
                              18431                 :                :                                   .createStmt = q->data,
                              18432                 :                :                                   .dropStmt = delq->data));
                              18433                 :                : 
                              18434                 :                :     /* Dump Statistics Comments */
 3088                         18435         [ -  + ]:            133 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       18436                 :UBC           0 :         dumpComment(fout, "STATISTICS", qstatsextname,
 2764                         18437                 :              0 :                     statsextinfo->dobj.namespace->dobj.name,
                              18438                 :              0 :                     statsextinfo->rolname,
                              18439                 :                :                     statsextinfo->dobj.catId, 0,
 3088 alvherre@alvh.no-ip.    18440                 :              0 :                     statsextinfo->dobj.dumpId);
                              18441                 :                : 
 2764 tgl@sss.pgh.pa.us       18442                 :CBC         133 :     PQclear(res);
 3088 alvherre@alvh.no-ip.    18443                 :            133 :     destroyPQExpBuffer(q);
                              18444                 :            133 :     destroyPQExpBuffer(delq);
 2764 tgl@sss.pgh.pa.us       18445                 :            133 :     destroyPQExpBuffer(query);
 2749                         18446                 :            133 :     free(qstatsextname);
                              18447                 :                : }
                              18448                 :                : 
                              18449                 :                : /*
                              18450                 :                :  * dumpConstraint
                              18451                 :                :  *    write out to fout a user-defined constraint
                              18452                 :                :  */
                              18453                 :                : static void
 1669 peter@eisentraut.org    18454                 :           2645 : dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
                              18455                 :                : {
 3524 tgl@sss.pgh.pa.us       18456                 :           2645 :     DumpOptions *dopt = fout->dopt;
 7945                         18457                 :           2645 :     TableInfo  *tbinfo = coninfo->contable;
                              18458                 :                :     PQExpBuffer q;
                              18459                 :                :     PQExpBuffer delq;
 3481 peter_e@gmx.net         18460                 :           2645 :     char       *tag = NULL;
                              18461                 :                :     char       *foreign;
                              18462                 :                : 
                              18463                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    18464         [ +  + ]:           2645 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       18465                 :             98 :         return;
                              18466                 :                : 
                              18467                 :           2547 :     q = createPQExpBuffer();
                              18468                 :           2547 :     delq = createPQExpBuffer();
                              18469                 :                : 
 1996 alvherre@alvh.no-ip.    18470                 :           4928 :     foreign = tbinfo &&
 1941 tgl@sss.pgh.pa.us       18471   [ +  +  -  + ]:           2547 :         tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              18472                 :                : 
 5752                         18473         [ +  + ]:           2547 :     if (coninfo->contype == 'p' ||
                              18474         [ +  + ]:           1298 :         coninfo->contype == 'u' ||
                              18475         [ +  + ]:           1063 :         coninfo->contype == 'x')
 7945                         18476                 :           1494 :     {
                              18477                 :                :         /* Index-related constraint */
                              18478                 :                :         IndxInfo   *indxinfo;
                              18479                 :                :         int         k;
                              18480                 :                : 
                              18481                 :           1494 :         indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
                              18482                 :                : 
                              18483         [ -  + ]:           1494 :         if (indxinfo == NULL)
 1247 tgl@sss.pgh.pa.us       18484                 :UBC           0 :             pg_fatal("missing index for constraint \"%s\"",
                              18485                 :                :                      coninfo->dobj.name);
                              18486                 :                : 
 3980 alvherre@alvh.no-ip.    18487         [ +  + ]:CBC        1494 :         if (dopt->binary_upgrade)
 4960 rhaas@postgresql.org    18488                 :            146 :             binary_upgrade_set_pg_class_oids(fout, q,
                              18489                 :                :                                              indxinfo->dobj.catId.oid);
                              18490                 :                : 
 1996 alvherre@alvh.no-ip.    18491                 :           1494 :         appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
 2749 tgl@sss.pgh.pa.us       18492                 :           1494 :                           fmtQualifiedDumpable(tbinfo));
 5752                         18493                 :           1494 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s ",
                              18494                 :           1494 :                           fmtId(coninfo->dobj.name));
                              18495                 :                : 
                              18496         [ +  + ]:           1494 :         if (coninfo->condef)
                              18497                 :                :         {
                              18498                 :                :             /* pg_get_constraintdef should have provided everything */
                              18499                 :             10 :             appendPQExpBuffer(q, "%s;\n", coninfo->condef);
                              18500                 :                :         }
                              18501                 :                :         else
                              18502                 :                :         {
 1096 drowley@postgresql.o    18503                 :           1484 :             appendPQExpBufferStr(q,
                              18504         [ +  + ]:           1484 :                                  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
                              18505                 :                : 
                              18506                 :                :             /*
                              18507                 :                :              * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
                              18508                 :                :              * indexes. Being able to create this was fixed, but we need to
                              18509                 :                :              * make the index distinct in order to be able to restore the
                              18510                 :                :              * dump.
                              18511                 :                :              */
  925 dgustafsson@postgres    18512   [ -  +  -  - ]:           1484 :             if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
 1096 drowley@postgresql.o    18513                 :UBC           0 :                 appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
 1096 drowley@postgresql.o    18514                 :CBC        1484 :             appendPQExpBufferStr(q, " (");
 2709 teodor@sigaev.ru        18515         [ +  + ]:           3597 :             for (k = 0; k < indxinfo->indnkeyattrs; k++)
                              18516                 :                :             {
 5752 tgl@sss.pgh.pa.us       18517                 :           2113 :                 int         indkey = (int) indxinfo->indkeys[k];
                              18518                 :                :                 const char *attname;
                              18519                 :                : 
                              18520         [ -  + ]:           2113 :                 if (indkey == InvalidAttrNumber)
 5752 tgl@sss.pgh.pa.us       18521                 :UBC           0 :                     break;
 5752 tgl@sss.pgh.pa.us       18522                 :CBC        2113 :                 attname = getAttrName(indkey, tbinfo);
                              18523                 :                : 
                              18524         [ +  + ]:           2113 :                 appendPQExpBuffer(q, "%s%s",
                              18525                 :                :                                   (k == 0) ? "" : ", ",
                              18526                 :                :                                   fmtId(attname));
                              18527                 :                :             }
  354 peter@eisentraut.org    18528         [ +  + ]:           1484 :             if (coninfo->conperiod)
                              18529                 :            116 :                 appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
                              18530                 :                : 
 2709 teodor@sigaev.ru        18531         [ +  + ]:           1484 :             if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
 2256 drowley@postgresql.o    18532                 :             20 :                 appendPQExpBufferStr(q, ") INCLUDE (");
                              18533                 :                : 
 2709 teodor@sigaev.ru        18534         [ +  + ]:           1524 :             for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
                              18535                 :                :             {
                              18536                 :             40 :                 int         indkey = (int) indxinfo->indkeys[k];
                              18537                 :                :                 const char *attname;
                              18538                 :                : 
                              18539         [ -  + ]:             40 :                 if (indkey == InvalidAttrNumber)
 2709 teodor@sigaev.ru        18540                 :UBC           0 :                     break;
 2709 teodor@sigaev.ru        18541                 :CBC          40 :                 attname = getAttrName(indkey, tbinfo);
                              18542                 :                : 
                              18543                 :             80 :                 appendPQExpBuffer(q, "%s%s",
                              18544         [ +  + ]:             40 :                                   (k == indxinfo->indnkeyattrs) ? "" : ", ",
                              18545                 :                :                                   fmtId(attname));
                              18546                 :                :             }
                              18547                 :                : 
 4310 heikki.linnakangas@i    18548                 :           1484 :             appendPQExpBufferChar(q, ')');
                              18549                 :                : 
 3535 tgl@sss.pgh.pa.us       18550         [ -  + ]:           1484 :             if (nonemptyReloptions(indxinfo->indreloptions))
                              18551                 :                :             {
 3535 tgl@sss.pgh.pa.us       18552                 :UBC           0 :                 appendPQExpBufferStr(q, " WITH (");
 3410 dean.a.rasheed@gmail    18553                 :              0 :                 appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
 3535 tgl@sss.pgh.pa.us       18554                 :              0 :                 appendPQExpBufferChar(q, ')');
                              18555                 :                :             }
                              18556                 :                : 
 5752 tgl@sss.pgh.pa.us       18557         [ +  + ]:CBC        1484 :             if (coninfo->condeferrable)
                              18558                 :                :             {
 4310 heikki.linnakangas@i    18559                 :             25 :                 appendPQExpBufferStr(q, " DEFERRABLE");
 5752 tgl@sss.pgh.pa.us       18560         [ +  + ]:             25 :                 if (coninfo->condeferred)
 4310 heikki.linnakangas@i    18561                 :             15 :                     appendPQExpBufferStr(q, " INITIALLY DEFERRED");
                              18562                 :                :             }
                              18563                 :                : 
                              18564                 :           1484 :             appendPQExpBufferStr(q, ";\n");
                              18565                 :                :         }
                              18566                 :                : 
                              18567                 :                :         /*
                              18568                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              18569                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              18570                 :                :          * similar code in dumpIndex!
                              18571                 :                :          */
                              18572                 :                : 
                              18573                 :                :         /* If the index is clustered, we need to record that. */
 7945 tgl@sss.pgh.pa.us       18574         [ +  + ]:           1494 :         if (indxinfo->indisclustered)
                              18575                 :                :         {
                              18576                 :             38 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2749                         18577                 :             38 :                               fmtQualifiedDumpable(tbinfo));
                              18578                 :                :             /* index name is not qualified in this syntax */
 7945                         18579                 :             38 :             appendPQExpBuffer(q, " ON %s;\n",
 7857                         18580                 :             38 :                               fmtId(indxinfo->dobj.name));
                              18581                 :                :         }
                              18582                 :                : 
                              18583                 :                :         /* If the index defines identity, we need to record that. */
 2595                         18584         [ -  + ]:           1494 :         if (indxinfo->indisreplident)
                              18585                 :                :         {
 2595 tgl@sss.pgh.pa.us       18586                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
                              18587                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              18588                 :                :             /* index name is not qualified in this syntax */
                              18589                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              18590                 :              0 :                               fmtId(indxinfo->dobj.name));
                              18591                 :                :         }
                              18592                 :                : 
                              18593                 :                :         /* Indexes can depend on extensions */
 2005 alvherre@alvh.no-ip.    18594                 :CBC        1494 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              18595                 :                :                                     "pg_catalog.pg_class", "INDEX",
                              18596                 :           1494 :                                     fmtQualifiedDumpable(indxinfo));
                              18597                 :                : 
 1996                         18598                 :           1494 :         appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
 2749 tgl@sss.pgh.pa.us       18599                 :           1494 :                           fmtQualifiedDumpable(tbinfo));
 7945                         18600                 :           1494 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7857                         18601                 :           1494 :                           fmtId(coninfo->dobj.name));
                              18602                 :                : 
 3481 peter_e@gmx.net         18603                 :           1494 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18604                 :                : 
 3440 sfrost@snowman.net      18605         [ +  - ]:           1494 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18606                 :           1494 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18607                 :           1494 :                          ARCHIVE_OPTS(.tag = tag,
                              18608                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18609                 :                :                                       .tablespace = indxinfo->tablespace,
                              18610                 :                :                                       .owner = tbinfo->rolname,
                              18611                 :                :                                       .description = "CONSTRAINT",
                              18612                 :                :                                       .section = SECTION_POST_DATA,
                              18613                 :                :                                       .createStmt = q->data,
                              18614                 :                :                                       .dropStmt = delq->data));
                              18615                 :                :     }
 7945 tgl@sss.pgh.pa.us       18616         [ +  + ]:           1053 :     else if (coninfo->contype == 'f')
                              18617                 :                :     {
                              18618                 :                :         char       *only;
                              18619                 :                : 
                              18620                 :                :         /*
                              18621                 :                :          * Foreign keys on partitioned tables are always declared as
                              18622                 :                :          * inheriting to partitions; for all other cases, emit them as
                              18623                 :                :          * applying ONLY directly to the named table, because that's how they
                              18624                 :                :          * work for regular inherited tables.
                              18625                 :                :          */
 2712 alvherre@alvh.no-ip.    18626         [ +  + ]:            171 :         only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
                              18627                 :                : 
                              18628                 :                :         /*
                              18629                 :                :          * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
                              18630                 :                :          * current table data is not processed
                              18631                 :                :          */
 1996                         18632                 :            171 :         appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
 2712                         18633                 :            171 :                           only, fmtQualifiedDumpable(tbinfo));
 7945 tgl@sss.pgh.pa.us       18634                 :            171 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7857                         18635                 :            171 :                           fmtId(coninfo->dobj.name),
 7945                         18636                 :            171 :                           coninfo->condef);
                              18637                 :                : 
 1996 alvherre@alvh.no-ip.    18638                 :            171 :         appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
 2712                         18639                 :            171 :                           only, fmtQualifiedDumpable(tbinfo));
 7945 tgl@sss.pgh.pa.us       18640                 :            171 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7857                         18641                 :            171 :                           fmtId(coninfo->dobj.name));
                              18642                 :                : 
 3481 peter_e@gmx.net         18643                 :            171 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18644                 :                : 
 3440 sfrost@snowman.net      18645         [ +  - ]:            171 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18646                 :            171 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18647                 :            171 :                          ARCHIVE_OPTS(.tag = tag,
                              18648                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              18649                 :                :                                       .owner = tbinfo->rolname,
                              18650                 :                :                                       .description = "FK CONSTRAINT",
                              18651                 :                :                                       .section = SECTION_POST_DATA,
                              18652                 :                :                                       .createStmt = q->data,
                              18653                 :                :                                       .dropStmt = delq->data));
                              18654                 :                :     }
  152                         18655   [ +  +  +  -  :            882 :     else if ((coninfo->contype == 'c' || coninfo->contype == 'n') && tbinfo)
                                              +  + ]
                              18656                 :                :     {
                              18657                 :                :         /* CHECK or invalid not-null constraint on a table */
                              18658                 :                : 
                              18659                 :                :         /* Ignore if not to be dumped separately, or if it was inherited */
 3628 tgl@sss.pgh.pa.us       18660   [ +  +  +  + ]:            716 :         if (coninfo->separate && coninfo->conislocal)
                              18661                 :                :         {
                              18662                 :                :             const char *keyword;
                              18663                 :                : 
  152 alvherre@alvh.no-ip.    18664         [ +  + ]:            113 :             if (coninfo->contype == 'c')
                              18665                 :             45 :                 keyword = "CHECK CONSTRAINT";
                              18666                 :                :             else
                              18667                 :             68 :                 keyword = "CONSTRAINT";
                              18668                 :                : 
                              18669                 :                :             /* not ONLY since we want it to propagate to children */
 1996                         18670                 :            113 :             appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
 2749 tgl@sss.pgh.pa.us       18671                 :            113 :                               fmtQualifiedDumpable(tbinfo));
 7945                         18672                 :            113 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7857                         18673                 :            113 :                               fmtId(coninfo->dobj.name),
 7945                         18674                 :            113 :                               coninfo->condef);
                              18675                 :                : 
 1996 alvherre@alvh.no-ip.    18676                 :            113 :             appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
 2749 tgl@sss.pgh.pa.us       18677                 :            113 :                               fmtQualifiedDumpable(tbinfo));
 7945                         18678                 :            113 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7857                         18679                 :            113 :                               fmtId(coninfo->dobj.name));
                              18680                 :                : 
 3481 peter_e@gmx.net         18681                 :            113 :             tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              18682                 :                : 
 3440 sfrost@snowman.net      18683         [ +  - ]:            113 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18684                 :            113 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18685                 :            113 :                              ARCHIVE_OPTS(.tag = tag,
                              18686                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              18687                 :                :                                           .owner = tbinfo->rolname,
                              18688                 :                :                                           .description = keyword,
                              18689                 :                :                                           .section = SECTION_POST_DATA,
                              18690                 :                :                                           .createStmt = q->data,
                              18691                 :                :                                           .dropStmt = delq->data));
                              18692                 :                :         }
                              18693                 :                :     }
   47 alvherre@kurilemu.de    18694         [ +  - ]:            166 :     else if (tbinfo == NULL)
                              18695                 :                :     {
                              18696                 :                :         /* CHECK, NOT NULL constraint on a domain */
 5736 bruce@momjian.us        18697                 :            166 :         TypeInfo   *tyinfo = coninfo->condomain;
                              18698                 :                : 
   47 alvherre@kurilemu.de    18699   [ +  +  -  + ]:            166 :         Assert(coninfo->contype == 'c' || coninfo->contype == 'n');
                              18700                 :                : 
                              18701                 :                :         /* Ignore if not to be dumped separately */
 7128 tgl@sss.pgh.pa.us       18702         [ +  + ]:            166 :         if (coninfo->separate)
                              18703                 :                :         {
                              18704                 :                :             const char *keyword;
                              18705                 :                : 
   47 alvherre@kurilemu.de    18706         [ +  - ]:              5 :             if (coninfo->contype == 'c')
                              18707                 :              5 :                 keyword = "CHECK CONSTRAINT";
                              18708                 :                :             else
   47 alvherre@kurilemu.de    18709                 :UBC           0 :                 keyword = "CONSTRAINT";
                              18710                 :                : 
 7945 tgl@sss.pgh.pa.us       18711                 :CBC           5 :             appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
 2749                         18712                 :              5 :                               fmtQualifiedDumpable(tyinfo));
 7945                         18713                 :              5 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7857                         18714                 :              5 :                               fmtId(coninfo->dobj.name),
 7945                         18715                 :              5 :                               coninfo->condef);
                              18716                 :                : 
 2749                         18717                 :              5 :             appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
                              18718                 :              5 :                               fmtQualifiedDumpable(tyinfo));
 7945                         18719                 :              5 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7857                         18720                 :              5 :                               fmtId(coninfo->dobj.name));
                              18721                 :                : 
 3481 peter_e@gmx.net         18722                 :              5 :             tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
                              18723                 :                : 
 3440 sfrost@snowman.net      18724         [ +  - ]:              5 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18725                 :              5 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    18726                 :              5 :                              ARCHIVE_OPTS(.tag = tag,
                              18727                 :                :                                           .namespace = tyinfo->dobj.namespace->dobj.name,
                              18728                 :                :                                           .owner = tyinfo->rolname,
                              18729                 :                :                                           .description = keyword,
                              18730                 :                :                                           .section = SECTION_POST_DATA,
                              18731                 :                :                                           .createStmt = q->data,
                              18732                 :                :                                           .dropStmt = delq->data));
                              18733                 :                : 
   52 alvherre@kurilemu.de    18734         [ +  - ]:              5 :             if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              18735                 :                :             {
                              18736                 :              5 :                 PQExpBuffer conprefix = createPQExpBuffer();
                              18737                 :              5 :                 char       *qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
                              18738                 :                : 
                              18739                 :              5 :                 appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
                              18740                 :              5 :                                   fmtId(coninfo->dobj.name));
                              18741                 :                : 
                              18742                 :              5 :                 dumpComment(fout, conprefix->data, qtypname,
                              18743                 :              5 :                             tyinfo->dobj.namespace->dobj.name,
                              18744                 :                :                             tyinfo->rolname,
                              18745                 :                :                             coninfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              18746                 :              5 :                 destroyPQExpBuffer(conprefix);
                              18747                 :              5 :                 free(qtypname);
                              18748                 :                :             }
                              18749                 :                :         }
                              18750                 :                :     }
                              18751                 :                :     else
                              18752                 :                :     {
 1247 tgl@sss.pgh.pa.us       18753                 :UBC           0 :         pg_fatal("unrecognized constraint type: %c",
                              18754                 :                :                  coninfo->contype);
                              18755                 :                :     }
                              18756                 :                : 
                              18757                 :                :     /* Dump Constraint Comments --- only works for table constraints */
 3440 sfrost@snowman.net      18758   [ +  +  +  + ]:CBC        2547 :     if (tbinfo && coninfo->separate &&
                              18759         [ +  + ]:           1808 :         coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 3524 tgl@sss.pgh.pa.us       18760                 :             53 :         dumpTableConstraintComment(fout, coninfo);
                              18761                 :                : 
 3481 peter_e@gmx.net         18762                 :           2547 :     free(tag);
 8520 tgl@sss.pgh.pa.us       18763                 :           2547 :     destroyPQExpBuffer(q);
                              18764                 :           2547 :     destroyPQExpBuffer(delq);
                              18765                 :                : }
                              18766                 :                : 
                              18767                 :                : /*
                              18768                 :                :  * dumpTableConstraintComment --- dump a constraint's comment if any
                              18769                 :                :  *
                              18770                 :                :  * This is split out because we need the function in two different places
                              18771                 :                :  * depending on whether the constraint is dumped as part of CREATE TABLE
                              18772                 :                :  * or as a separate ALTER command.
                              18773                 :                :  */
                              18774                 :                : static void
 1669 peter@eisentraut.org    18775                 :             96 : dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
                              18776                 :                : {
 7571 tgl@sss.pgh.pa.us       18777                 :             96 :     TableInfo  *tbinfo = coninfo->contable;
 2749                         18778                 :             96 :     PQExpBuffer conprefix = createPQExpBuffer();
                              18779                 :                :     char       *qtabname;
                              18780                 :                : 
                              18781                 :             96 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              18782                 :                : 
                              18783                 :             96 :     appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
 7571                         18784                 :             96 :                       fmtId(coninfo->dobj.name));
                              18785                 :                : 
 3440 sfrost@snowman.net      18786         [ +  - ]:             96 :     if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       18787                 :             96 :         dumpComment(fout, conprefix->data, qtabname,
 3440 sfrost@snowman.net      18788                 :             96 :                     tbinfo->dobj.namespace->dobj.name,
                              18789                 :                :                     tbinfo->rolname,
                              18790                 :                :                     coninfo->dobj.catId, 0,
 2999 tgl@sss.pgh.pa.us       18791         [ +  + ]:             96 :                     coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
                              18792                 :                : 
 2749                         18793                 :             96 :     destroyPQExpBuffer(conprefix);
                              18794                 :             96 :     free(qtabname);
 7571                         18795                 :             96 : }
                              18796                 :                : 
                              18797                 :                : static inline SeqType
  402 nathan@postgresql.or    18798                 :            656 : parse_sequence_type(const char *name)
                              18799                 :                : {
                              18800         [ +  - ]:           1461 :     for (int i = 0; i < lengthof(SeqTypeNames); i++)
                              18801                 :                :     {
                              18802         [ +  + ]:           1461 :         if (strcmp(SeqTypeNames[i], name) == 0)
                              18803                 :            656 :             return (SeqType) i;
                              18804                 :                :     }
                              18805                 :                : 
  402 nathan@postgresql.or    18806                 :UBC           0 :     pg_fatal("unrecognized sequence type: %s", name);
                              18807                 :                :     return (SeqType) 0;         /* keep compiler quiet */
                              18808                 :                : }
                              18809                 :                : 
                              18810                 :                : /*
                              18811                 :                :  * bsearch() comparator for SequenceItem
                              18812                 :                :  */
                              18813                 :                : static int
  402 nathan@postgresql.or    18814                 :CBC        3014 : SequenceItemCmp(const void *p1, const void *p2)
                              18815                 :                : {
                              18816                 :           3014 :     SequenceItem v1 = *((const SequenceItem *) p1);
                              18817                 :           3014 :     SequenceItem v2 = *((const SequenceItem *) p2);
                              18818                 :                : 
                              18819                 :           3014 :     return pg_cmp_u32(v1.oid, v2.oid);
                              18820                 :                : }
                              18821                 :                : 
                              18822                 :                : /*
                              18823                 :                :  * collectSequences
                              18824                 :                :  *
                              18825                 :                :  * Construct a table of sequence information.  This table is sorted by OID for
                              18826                 :                :  * speed in lookup.
                              18827                 :                :  */
                              18828                 :                : static void
                              18829                 :            185 : collectSequences(Archive *fout)
                              18830                 :                : {
                              18831                 :                :     PGresult   *res;
                              18832                 :                :     const char *query;
                              18833                 :                : 
                              18834                 :                :     /*
                              18835                 :                :      * Before Postgres 10, sequence metadata is in the sequence itself.  With
                              18836                 :                :      * some extra effort, we might be able to use the sorted table for those
                              18837                 :                :      * versions, but for now it seems unlikely to be worth it.
                              18838                 :                :      *
                              18839                 :                :      * Since version 18, we can gather the sequence data in this query with
                              18840                 :                :      * pg_get_sequence_data(), but we only do so for non-schema-only dumps.
                              18841                 :                :      */
                              18842         [ -  + ]:            185 :     if (fout->remoteVersion < 100000)
  402 nathan@postgresql.or    18843                 :UBC           0 :         return;
  402 nathan@postgresql.or    18844         [ +  - ]:CBC         185 :     else if (fout->remoteVersion < 180000 ||
  285                         18845   [ +  +  +  + ]:            185 :              (!fout->dopt->dumpData && !fout->dopt->sequence_data))
  402                         18846                 :              8 :         query = "SELECT seqrelid, format_type(seqtypid, NULL), "
                              18847                 :                :             "seqstart, seqincrement, "
                              18848                 :                :             "seqmax, seqmin, "
                              18849                 :                :             "seqcache, seqcycle, "
                              18850                 :                :             "NULL, 'f' "
                              18851                 :                :             "FROM pg_catalog.pg_sequence "
                              18852                 :                :             "ORDER BY seqrelid";
                              18853                 :                :     else
                              18854                 :            177 :         query = "SELECT seqrelid, format_type(seqtypid, NULL), "
                              18855                 :                :             "seqstart, seqincrement, "
                              18856                 :                :             "seqmax, seqmin, "
                              18857                 :                :             "seqcache, seqcycle, "
                              18858                 :                :             "last_value, is_called "
                              18859                 :                :             "FROM pg_catalog.pg_sequence, "
                              18860                 :                :             "pg_get_sequence_data(seqrelid) "
                              18861                 :                :             "ORDER BY seqrelid;";
                              18862                 :                : 
                              18863                 :            185 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                              18864                 :                : 
                              18865                 :            185 :     nsequences = PQntuples(res);
                              18866                 :            185 :     sequences = (SequenceItem *) pg_malloc(nsequences * sizeof(SequenceItem));
                              18867                 :                : 
                              18868         [ +  + ]:            841 :     for (int i = 0; i < nsequences; i++)
                              18869                 :                :     {
                              18870                 :            656 :         sequences[i].oid = atooid(PQgetvalue(res, i, 0));
                              18871                 :            656 :         sequences[i].seqtype = parse_sequence_type(PQgetvalue(res, i, 1));
                              18872                 :            656 :         sequences[i].startv = strtoi64(PQgetvalue(res, i, 2), NULL, 10);
                              18873                 :            656 :         sequences[i].incby = strtoi64(PQgetvalue(res, i, 3), NULL, 10);
                              18874                 :            656 :         sequences[i].maxv = strtoi64(PQgetvalue(res, i, 4), NULL, 10);
                              18875                 :            656 :         sequences[i].minv = strtoi64(PQgetvalue(res, i, 5), NULL, 10);
                              18876                 :            656 :         sequences[i].cache = strtoi64(PQgetvalue(res, i, 6), NULL, 10);
                              18877                 :            656 :         sequences[i].cycled = (strcmp(PQgetvalue(res, i, 7), "t") == 0);
                              18878                 :            656 :         sequences[i].last_value = strtoi64(PQgetvalue(res, i, 8), NULL, 10);
                              18879                 :            656 :         sequences[i].is_called = (strcmp(PQgetvalue(res, i, 9), "t") == 0);
                              18880                 :                :     }
                              18881                 :                : 
                              18882                 :            185 :     PQclear(res);
                              18883                 :                : }
                              18884                 :                : 
                              18885                 :                : /*
                              18886                 :                :  * dumpSequence
                              18887                 :                :  *    write the declaration (not data) of one user-defined sequence
                              18888                 :                :  */
                              18889                 :                : static void
 1669 peter@eisentraut.org    18890                 :            393 : dumpSequence(Archive *fout, const TableInfo *tbinfo)
                              18891                 :                : {
 3524 tgl@sss.pgh.pa.us       18892                 :            393 :     DumpOptions *dopt = fout->dopt;
                              18893                 :                :     SequenceItem *seq;
                              18894                 :                :     bool        is_ascending;
                              18895                 :                :     int64       default_minv,
                              18896                 :                :                 default_maxv;
 9278 bruce@momjian.us        18897                 :            393 :     PQExpBuffer query = createPQExpBuffer();
 9195                         18898                 :            393 :     PQExpBuffer delqry = createPQExpBuffer();
                              18899                 :                :     char       *qseqname;
 1248 peter@eisentraut.org    18900                 :            393 :     TableInfo  *owning_tab = NULL;
                              18901                 :                : 
 2749 tgl@sss.pgh.pa.us       18902                 :            393 :     qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
                              18903                 :                : 
                              18904                 :                :     /*
                              18905                 :                :      * For versions >= 10, the sequence information is gathered in a sorted
                              18906                 :                :      * table before any calls to dumpSequence().  See collectSequences() for
                              18907                 :                :      * more information.
                              18908                 :                :      */
 3182 peter_e@gmx.net         18909         [ +  - ]:            393 :     if (fout->remoteVersion >= 100000)
                              18910                 :                :     {
  402 nathan@postgresql.or    18911                 :            393 :         SequenceItem key = {0};
                              18912                 :                : 
                              18913         [ -  + ]:            393 :         Assert(sequences);
                              18914                 :                : 
                              18915                 :            393 :         key.oid = tbinfo->dobj.catId.oid;
                              18916                 :            393 :         seq = bsearch(&key, sequences, nsequences,
                              18917                 :                :                       sizeof(SequenceItem), SequenceItemCmp);
                              18918                 :                :     }
                              18919                 :                :     else
                              18920                 :                :     {
                              18921                 :                :         PGresult   *res;
                              18922                 :                : 
                              18923                 :                :         /*
                              18924                 :                :          * Before PostgreSQL 10, sequence metadata is in the sequence itself.
                              18925                 :                :          *
                              18926                 :                :          * Note: it might seem that 'bigint' potentially needs to be
                              18927                 :                :          * schema-qualified, but actually that's a keyword.
                              18928                 :                :          */
 6322 tgl@sss.pgh.pa.us       18929                 :UBC           0 :         appendPQExpBuffer(query,
                              18930                 :                :                           "SELECT 'bigint' AS sequence_type, "
                              18931                 :                :                           "start_value, increment_by, max_value, min_value, "
                              18932                 :                :                           "cache_value, is_cycled FROM %s",
 2749                         18933                 :              0 :                           fmtQualifiedDumpable(tbinfo));
                              18934                 :                : 
  402 nathan@postgresql.or    18935                 :              0 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              18936                 :                : 
                              18937         [ #  # ]:              0 :         if (PQntuples(res) != 1)
                              18938                 :              0 :             pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              18939                 :                :                               "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              18940                 :                :                               PQntuples(res)),
                              18941                 :                :                      tbinfo->dobj.name, PQntuples(res));
                              18942                 :                : 
                              18943                 :              0 :         seq = pg_malloc0(sizeof(SequenceItem));
                              18944                 :              0 :         seq->seqtype = parse_sequence_type(PQgetvalue(res, 0, 0));
                              18945                 :              0 :         seq->startv = strtoi64(PQgetvalue(res, 0, 1), NULL, 10);
                              18946                 :              0 :         seq->incby = strtoi64(PQgetvalue(res, 0, 2), NULL, 10);
                              18947                 :              0 :         seq->maxv = strtoi64(PQgetvalue(res, 0, 3), NULL, 10);
                              18948                 :              0 :         seq->minv = strtoi64(PQgetvalue(res, 0, 4), NULL, 10);
                              18949                 :              0 :         seq->cache = strtoi64(PQgetvalue(res, 0, 5), NULL, 10);
                              18950                 :              0 :         seq->cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
                              18951                 :                : 
                              18952                 :              0 :         PQclear(res);
                              18953                 :                :     }
                              18954                 :                : 
                              18955                 :                :     /* Calculate default limits for a sequence of this type */
  402 nathan@postgresql.or    18956                 :CBC         393 :     is_ascending = (seq->incby >= 0);
                              18957         [ +  + ]:            393 :     if (seq->seqtype == SEQTYPE_SMALLINT)
                              18958                 :                :     {
 2755 tgl@sss.pgh.pa.us       18959         [ +  + ]:             25 :         default_minv = is_ascending ? 1 : PG_INT16_MIN;
                              18960         [ +  + ]:             25 :         default_maxv = is_ascending ? PG_INT16_MAX : -1;
                              18961                 :                :     }
  402 nathan@postgresql.or    18962         [ +  + ]:            368 :     else if (seq->seqtype == SEQTYPE_INTEGER)
                              18963                 :                :     {
 2755 tgl@sss.pgh.pa.us       18964         [ +  + ]:            302 :         default_minv = is_ascending ? 1 : PG_INT32_MIN;
                              18965         [ +  + ]:            302 :         default_maxv = is_ascending ? PG_INT32_MAX : -1;
                              18966                 :                :     }
  402 nathan@postgresql.or    18967         [ +  - ]:             66 :     else if (seq->seqtype == SEQTYPE_BIGINT)
                              18968                 :                :     {
 2755 tgl@sss.pgh.pa.us       18969         [ +  + ]:             66 :         default_minv = is_ascending ? 1 : PG_INT64_MIN;
                              18970         [ +  + ]:             66 :         default_maxv = is_ascending ? PG_INT64_MAX : -1;
                              18971                 :                :     }
                              18972                 :                :     else
                              18973                 :                :     {
  402 nathan@postgresql.or    18974                 :UBC           0 :         pg_fatal("unrecognized sequence type: %d", seq->seqtype);
                              18975                 :                :         default_minv = default_maxv = 0;    /* keep compiler quiet */
                              18976                 :                :     }
                              18977                 :                : 
                              18978                 :                :     /*
                              18979                 :                :      * Identity sequences are not to be dropped separately.
                              18980                 :                :      */
 3075 peter_e@gmx.net         18981         [ +  + ]:CBC         393 :     if (!tbinfo->is_identity_sequence)
                              18982                 :                :     {
 2749 tgl@sss.pgh.pa.us       18983                 :            245 :         appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
                              18984                 :            245 :                           fmtQualifiedDumpable(tbinfo));
                              18985                 :                :     }
                              18986                 :                : 
 4698                         18987                 :            393 :     resetPQExpBuffer(query);
                              18988                 :                : 
 3980 alvherre@alvh.no-ip.    18989         [ +  + ]:            393 :     if (dopt->binary_upgrade)
                              18990                 :                :     {
 4698 tgl@sss.pgh.pa.us       18991                 :             66 :         binary_upgrade_set_pg_class_oids(fout, query,
  430 nathan@postgresql.or    18992                 :             66 :                                          tbinfo->dobj.catId.oid);
                              18993                 :                : 
                              18994                 :                :         /*
                              18995                 :                :          * In older PG versions a sequence will have a pg_type entry, but v14
                              18996                 :                :          * and up don't use that, so don't attempt to preserve the type OID.
                              18997                 :                :          */
                              18998                 :                :     }
                              18999                 :                : 
 3075 peter_e@gmx.net         19000         [ +  + ]:            393 :     if (tbinfo->is_identity_sequence)
                              19001                 :                :     {
 1248 peter@eisentraut.org    19002                 :            148 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              19003                 :                : 
 3075 peter_e@gmx.net         19004                 :            148 :         appendPQExpBuffer(query,
                              19005                 :                :                           "ALTER TABLE %s ",
 2749 tgl@sss.pgh.pa.us       19006                 :            148 :                           fmtQualifiedDumpable(owning_tab));
 3075 peter_e@gmx.net         19007                 :            148 :         appendPQExpBuffer(query,
                              19008                 :                :                           "ALTER COLUMN %s ADD GENERATED ",
 2999 tgl@sss.pgh.pa.us       19009                 :            148 :                           fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
 3075 peter_e@gmx.net         19010         [ +  + ]:            148 :         if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
 2256 drowley@postgresql.o    19011                 :            108 :             appendPQExpBufferStr(query, "ALWAYS");
 3075 peter_e@gmx.net         19012         [ +  - ]:             40 :         else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
 2256 drowley@postgresql.o    19013                 :             40 :             appendPQExpBufferStr(query, "BY DEFAULT");
 3075 peter_e@gmx.net         19014                 :            148 :         appendPQExpBuffer(query, " AS IDENTITY (\n    SEQUENCE NAME %s\n",
 2749 tgl@sss.pgh.pa.us       19015                 :            148 :                           fmtQualifiedDumpable(tbinfo));
                              19016                 :                : 
                              19017                 :                :         /*
                              19018                 :                :          * Emit persistence option only if it's different from the owning
                              19019                 :                :          * table's.  This avoids using this new syntax unnecessarily.
                              19020                 :                :          */
  354                         19021         [ +  + ]:            148 :         if (tbinfo->relpersistence != owning_tab->relpersistence)
                              19022                 :             10 :             appendPQExpBuffer(query, "    %s\n",
                              19023         [ +  + ]:             10 :                               tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              19024                 :                :                               "UNLOGGED" : "LOGGED");
                              19025                 :                :     }
                              19026                 :                :     else
                              19027                 :                :     {
 3075 peter_e@gmx.net         19028                 :            245 :         appendPQExpBuffer(query,
                              19029                 :                :                           "CREATE %sSEQUENCE %s\n",
 1248 peter@eisentraut.org    19030         [ +  + ]:            245 :                           tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              19031                 :                :                           "UNLOGGED " : "",
 2749 tgl@sss.pgh.pa.us       19032                 :            245 :                           fmtQualifiedDumpable(tbinfo));
                              19033                 :                : 
  402 nathan@postgresql.or    19034         [ +  + ]:            245 :         if (seq->seqtype != SEQTYPE_BIGINT)
                              19035                 :            194 :             appendPQExpBuffer(query, "    AS %s\n", SeqTypeNames[seq->seqtype]);
                              19036                 :                :     }
                              19037                 :                : 
                              19038                 :            393 :     appendPQExpBuffer(query, "    START WITH " INT64_FORMAT "\n", seq->startv);
                              19039                 :                : 
                              19040                 :            393 :     appendPQExpBuffer(query, "    INCREMENT BY " INT64_FORMAT "\n", seq->incby);
                              19041                 :                : 
                              19042         [ +  + ]:            393 :     if (seq->minv != default_minv)
                              19043                 :             15 :         appendPQExpBuffer(query, "    MINVALUE " INT64_FORMAT "\n", seq->minv);
                              19044                 :                :     else
 4310 heikki.linnakangas@i    19045                 :            378 :         appendPQExpBufferStr(query, "    NO MINVALUE\n");
                              19046                 :                : 
  402 nathan@postgresql.or    19047         [ +  + ]:            393 :     if (seq->maxv != default_maxv)
                              19048                 :             15 :         appendPQExpBuffer(query, "    MAXVALUE " INT64_FORMAT "\n", seq->maxv);
                              19049                 :                :     else
 4310 heikki.linnakangas@i    19050                 :            378 :         appendPQExpBufferStr(query, "    NO MAXVALUE\n");
                              19051                 :                : 
 4698 tgl@sss.pgh.pa.us       19052                 :            393 :     appendPQExpBuffer(query,
                              19053                 :                :                       "    CACHE " INT64_FORMAT "%s",
  402 nathan@postgresql.or    19054         [ +  + ]:            393 :                       seq->cache, (seq->cycled ? "\n    CYCLE" : ""));
                              19055                 :                : 
 3075 peter_e@gmx.net         19056         [ +  + ]:            393 :     if (tbinfo->is_identity_sequence)
                              19057                 :            148 :         appendPQExpBufferStr(query, "\n);\n");
                              19058                 :                :     else
                              19059                 :            245 :         appendPQExpBufferStr(query, ";\n");
                              19060                 :                : 
                              19061                 :                :     /* binary_upgrade:  no need to clear TOAST table oid */
                              19062                 :                : 
 3980 alvherre@alvh.no-ip.    19063         [ +  + ]:            393 :     if (dopt->binary_upgrade)
 4698 tgl@sss.pgh.pa.us       19064                 :             66 :         binary_upgrade_extension_member(query, &tbinfo->dobj,
                              19065                 :                :                                         "SEQUENCE", qseqname,
 2749                         19066                 :             66 :                                         tbinfo->dobj.namespace->dobj.name);
                              19067                 :                : 
 3440 sfrost@snowman.net      19068         [ +  - ]:            393 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19069                 :            393 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    19070                 :            393 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19071                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19072                 :                :                                   .owner = tbinfo->rolname,
                              19073                 :                :                                   .description = "SEQUENCE",
                              19074                 :                :                                   .section = SECTION_PRE_DATA,
                              19075                 :                :                                   .createStmt = query->data,
                              19076                 :                :                                   .dropStmt = delqry->data));
                              19077                 :                : 
                              19078                 :                :     /*
                              19079                 :                :      * If the sequence is owned by a table column, emit the ALTER for it as a
                              19080                 :                :      * separate TOC entry immediately following the sequence's own entry. It's
                              19081                 :                :      * OK to do this rather than using full sorting logic, because the
                              19082                 :                :      * dependency that tells us it's owned will have forced the table to be
                              19083                 :                :      * created first.  We can't just include the ALTER in the TOC entry
                              19084                 :                :      * because it will fail if we haven't reassigned the sequence owner to
                              19085                 :                :      * match the table's owner.
                              19086                 :                :      *
                              19087                 :                :      * We need not schema-qualify the table reference because both sequence
                              19088                 :                :      * and table must be in the same schema.
                              19089                 :                :      */
 3075 peter_e@gmx.net         19090   [ +  +  +  + ]:            393 :     if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
                              19091                 :                :     {
 1113 drowley@postgresql.o    19092                 :            149 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              19093                 :                : 
 3165 sfrost@snowman.net      19094         [ -  + ]:            149 :         if (owning_tab == NULL)
 1247 tgl@sss.pgh.pa.us       19095                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                              19096                 :                :                      tbinfo->owning_tab, tbinfo->dobj.catId.oid);
                              19097                 :                : 
 3165 sfrost@snowman.net      19098         [ +  + ]:CBC         149 :         if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19099                 :                :         {
 4698 tgl@sss.pgh.pa.us       19100                 :            147 :             resetPQExpBuffer(query);
                              19101                 :            147 :             appendPQExpBuffer(query, "ALTER SEQUENCE %s",
 2749                         19102                 :            147 :                               fmtQualifiedDumpable(tbinfo));
 4698                         19103                 :            147 :             appendPQExpBuffer(query, " OWNED BY %s",
 2749                         19104                 :            147 :                               fmtQualifiedDumpable(owning_tab));
 4698                         19105                 :            147 :             appendPQExpBuffer(query, ".%s;\n",
 2999                         19106                 :            147 :                               fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
                              19107                 :                : 
 3440 sfrost@snowman.net      19108         [ +  - ]:            147 :             if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19109                 :            147 :                 ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    19110                 :            147 :                              ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19111                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              19112                 :                :                                           .owner = tbinfo->rolname,
                              19113                 :                :                                           .description = "SEQUENCE OWNED BY",
                              19114                 :                :                                           .section = SECTION_PRE_DATA,
                              19115                 :                :                                           .createStmt = query->data,
                              19116                 :                :                                           .deps = &(tbinfo->dobj.dumpId),
                              19117                 :                :                                           .nDeps = 1));
                              19118                 :                :         }
                              19119                 :                :     }
                              19120                 :                : 
                              19121                 :                :     /* Dump Sequence Comments and Security Labels */
 3440 sfrost@snowman.net      19122         [ -  + ]:            393 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       19123                 :UBC           0 :         dumpComment(fout, "SEQUENCE", qseqname,
 3440 sfrost@snowman.net      19124                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19125                 :              0 :                     tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              19126                 :                : 
 3440 sfrost@snowman.net      19127         [ -  + ]:CBC         393 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2749 tgl@sss.pgh.pa.us       19128                 :UBC           0 :         dumpSecLabel(fout, "SEQUENCE", qseqname,
 3440 sfrost@snowman.net      19129                 :              0 :                      tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19130                 :              0 :                      tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              19131                 :                : 
  402 nathan@postgresql.or    19132         [ -  + ]:CBC         393 :     if (fout->remoteVersion < 100000)
  402 nathan@postgresql.or    19133                 :UBC           0 :         pg_free(seq);
 8800 tgl@sss.pgh.pa.us       19134                 :CBC         393 :     destroyPQExpBuffer(query);
                              19135                 :            393 :     destroyPQExpBuffer(delqry);
 2749                         19136                 :            393 :     free(qseqname);
10384 vadim4o@yahoo.com       19137                 :            393 : }
                              19138                 :                : 
                              19139                 :                : /*
                              19140                 :                :  * dumpSequenceData
                              19141                 :                :  *    write the data of one user-defined sequence
                              19142                 :                :  */
                              19143                 :                : static void
 1669 peter@eisentraut.org    19144                 :            411 : dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
                              19145                 :                : {
 4698 tgl@sss.pgh.pa.us       19146                 :            411 :     TableInfo  *tbinfo = tdinfo->tdtable;
                              19147                 :                :     int64       last;
                              19148                 :                :     bool        called;
                              19149                 :            411 :     PQExpBuffer query = createPQExpBuffer();
                              19150                 :                : 
                              19151                 :                :     /*
                              19152                 :                :      * For versions >= 18, the sequence information is gathered in the sorted
                              19153                 :                :      * array before any calls to dumpSequenceData().  See collectSequences()
                              19154                 :                :      * for more information.
                              19155                 :                :      *
                              19156                 :                :      * For older versions, we have to query the sequence relations
                              19157                 :                :      * individually.
                              19158                 :                :      */
  402 nathan@postgresql.or    19159         [ -  + ]:            411 :     if (fout->remoteVersion < 180000)
                              19160                 :                :     {
                              19161                 :                :         PGresult   *res;
                              19162                 :                : 
  402 nathan@postgresql.or    19163                 :UBC           0 :         appendPQExpBuffer(query,
                              19164                 :                :                           "SELECT last_value, is_called FROM %s",
                              19165                 :              0 :                           fmtQualifiedDumpable(tbinfo));
                              19166                 :                : 
                              19167                 :              0 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19168                 :                : 
                              19169         [ #  # ]:              0 :         if (PQntuples(res) != 1)
                              19170                 :              0 :             pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              19171                 :                :                               "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              19172                 :                :                               PQntuples(res)),
                              19173                 :                :                      tbinfo->dobj.name, PQntuples(res));
                              19174                 :                : 
                              19175                 :              0 :         last = strtoi64(PQgetvalue(res, 0, 0), NULL, 10);
                              19176                 :              0 :         called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
                              19177                 :                : 
                              19178                 :              0 :         PQclear(res);
                              19179                 :                :     }
                              19180                 :                :     else
                              19181                 :                :     {
  402 nathan@postgresql.or    19182                 :CBC         411 :         SequenceItem key = {0};
                              19183                 :                :         SequenceItem *entry;
                              19184                 :                : 
                              19185         [ -  + ]:            411 :         Assert(sequences);
                              19186         [ -  + ]:            411 :         Assert(tbinfo->dobj.catId.oid);
                              19187                 :                : 
                              19188                 :            411 :         key.oid = tbinfo->dobj.catId.oid;
                              19189                 :            411 :         entry = bsearch(&key, sequences, nsequences,
                              19190                 :                :                         sizeof(SequenceItem), SequenceItemCmp);
                              19191                 :                : 
                              19192                 :            411 :         last = entry->last_value;
                              19193                 :            411 :         called = entry->is_called;
                              19194                 :                :     }
                              19195                 :                : 
 4698 tgl@sss.pgh.pa.us       19196                 :            411 :     resetPQExpBuffer(query);
 4310 heikki.linnakangas@i    19197                 :            411 :     appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
 2749 tgl@sss.pgh.pa.us       19198                 :            411 :     appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
  402 nathan@postgresql.or    19199         [ +  + ]:            411 :     appendPQExpBuffer(query, ", " INT64_FORMAT ", %s);\n",
                              19200                 :                :                       last, (called ? "true" : "false"));
                              19201                 :                : 
 3152 sfrost@snowman.net      19202         [ +  - ]:            411 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
 3440                         19203                 :            411 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 2409 alvherre@alvh.no-ip.    19204                 :            411 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              19205                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19206                 :                :                                   .owner = tbinfo->rolname,
                              19207                 :                :                                   .description = "SEQUENCE SET",
                              19208                 :                :                                   .section = SECTION_DATA,
                              19209                 :                :                                   .createStmt = query->data,
                              19210                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              19211                 :                :                                   .nDeps = 1));
                              19212                 :                : 
 4698 tgl@sss.pgh.pa.us       19213                 :            411 :     destroyPQExpBuffer(query);
                              19214                 :            411 : }
                              19215                 :                : 
                              19216                 :                : /*
                              19217                 :                :  * dumpTrigger
                              19218                 :                :  *    write the declaration of one user-defined table trigger
                              19219                 :                :  */
                              19220                 :                : static void
 1669 peter@eisentraut.org    19221                 :            553 : dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
                              19222                 :                : {
 3524 tgl@sss.pgh.pa.us       19223                 :            553 :     DumpOptions *dopt = fout->dopt;
 7945                         19224                 :            553 :     TableInfo  *tbinfo = tginfo->tgtable;
                              19225                 :                :     PQExpBuffer query;
                              19226                 :                :     PQExpBuffer delqry;
                              19227                 :                :     PQExpBuffer trigprefix;
                              19228                 :                :     PQExpBuffer trigidentity;
                              19229                 :                :     char       *qtabname;
                              19230                 :                :     char       *tag;
                              19231                 :                : 
                              19232                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    19233         [ +  + ]:            553 :     if (!dopt->dumpSchema)
 8422 tgl@sss.pgh.pa.us       19234                 :             31 :         return;
                              19235                 :                : 
 7945                         19236                 :            522 :     query = createPQExpBuffer();
                              19237                 :            522 :     delqry = createPQExpBuffer();
 2749                         19238                 :            522 :     trigprefix = createPQExpBuffer();
 2005 alvherre@alvh.no-ip.    19239                 :            522 :     trigidentity = createPQExpBuffer();
                              19240                 :                : 
 2749 tgl@sss.pgh.pa.us       19241                 :            522 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              19242                 :                : 
 2005 alvherre@alvh.no-ip.    19243                 :            522 :     appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
                              19244                 :            522 :     appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
                              19245                 :                : 
  601 peter@eisentraut.org    19246                 :            522 :     appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
 2005 alvherre@alvh.no-ip.    19247                 :            522 :     appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
                              19248                 :                : 
                              19249                 :                :     /* Triggers can depend on extensions */
                              19250                 :            522 :     append_depends_on_extension(fout, query, &tginfo->dobj,
                              19251                 :                :                                 "pg_catalog.pg_trigger", "TRIGGER",
                              19252                 :            522 :                                 trigidentity->data);
                              19253                 :                : 
 1340                         19254         [ +  + ]:            522 :     if (tginfo->tgispartition)
                              19255                 :                :     {
                              19256         [ -  + ]:            127 :         Assert(tbinfo->ispartition);
                              19257                 :                : 
                              19258                 :                :         /*
                              19259                 :                :          * Partition triggers only appear here because their 'tgenabled' flag
                              19260                 :                :          * differs from its parent's.  The trigger is created already, so
                              19261                 :                :          * remove the CREATE and replace it with an ALTER.  (Clear out the
                              19262                 :                :          * DROP query too, so that pg_dump --create does not cause errors.)
                              19263                 :                :          */
 1513                         19264                 :            127 :         resetPQExpBuffer(query);
                              19265                 :            127 :         resetPQExpBuffer(delqry);
                              19266                 :            127 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
                              19267         [ -  + ]:            127 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
                              19268                 :            127 :                           fmtQualifiedDumpable(tbinfo));
                              19269   [ +  -  +  +  :            127 :         switch (tginfo->tgenabled)
                                                 - ]
                              19270                 :                :         {
                              19271                 :             44 :             case 'f':
                              19272                 :                :             case 'D':
                              19273                 :             44 :                 appendPQExpBufferStr(query, "DISABLE");
                              19274                 :             44 :                 break;
 1513 alvherre@alvh.no-ip.    19275                 :UBC           0 :             case 't':
                              19276                 :                :             case 'O':
                              19277                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
                              19278                 :              0 :                 break;
 1513 alvherre@alvh.no-ip.    19279                 :CBC          39 :             case 'R':
                              19280                 :             39 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
                              19281                 :             39 :                 break;
                              19282                 :             44 :             case 'A':
                              19283                 :             44 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
                              19284                 :             44 :                 break;
                              19285                 :                :         }
                              19286                 :            127 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
                              19287                 :            127 :                           fmtId(tginfo->dobj.name));
                              19288                 :                :     }
                              19289   [ +  -  -  + ]:            395 :     else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
                              19290                 :                :     {
 1996 alvherre@alvh.no-ip.    19291                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
                              19292         [ #  # ]:              0 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
 2749 tgl@sss.pgh.pa.us       19293                 :              0 :                           fmtQualifiedDumpable(tbinfo));
 6746 JanWieck@Yahoo.com      19294   [ #  #  #  # ]:              0 :         switch (tginfo->tgenabled)
                              19295                 :                :         {
                              19296                 :              0 :             case 'D':
                              19297                 :                :             case 'f':
 4310 heikki.linnakangas@i    19298                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 6746 JanWieck@Yahoo.com      19299                 :              0 :                 break;
                              19300                 :              0 :             case 'A':
 4310 heikki.linnakangas@i    19301                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 6746 JanWieck@Yahoo.com      19302                 :              0 :                 break;
                              19303                 :              0 :             case 'R':
 4310 heikki.linnakangas@i    19304                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 6746 JanWieck@Yahoo.com      19305                 :              0 :                 break;
                              19306                 :              0 :             default:
 4310 heikki.linnakangas@i    19307                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 6746 JanWieck@Yahoo.com      19308                 :              0 :                 break;
                              19309                 :                :         }
                              19310                 :              0 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
 7319 tgl@sss.pgh.pa.us       19311                 :              0 :                           fmtId(tginfo->dobj.name));
                              19312                 :                :     }
                              19313                 :                : 
 2749 tgl@sss.pgh.pa.us       19314                 :CBC         522 :     appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
 5323                         19315                 :            522 :                       fmtId(tginfo->dobj.name));
                              19316                 :                : 
 3481 peter_e@gmx.net         19317                 :            522 :     tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
                              19318                 :                : 
 3440 sfrost@snowman.net      19319         [ +  - ]:            522 :     if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19320                 :            522 :         ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    19321                 :            522 :                      ARCHIVE_OPTS(.tag = tag,
                              19322                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19323                 :                :                                   .owner = tbinfo->rolname,
                              19324                 :                :                                   .description = "TRIGGER",
                              19325                 :                :                                   .section = SECTION_POST_DATA,
                              19326                 :                :                                   .createStmt = query->data,
                              19327                 :                :                                   .dropStmt = delqry->data));
                              19328                 :                : 
 3440 sfrost@snowman.net      19329         [ -  + ]:            522 :     if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       19330                 :UBC           0 :         dumpComment(fout, trigprefix->data, qtabname,
 3440 sfrost@snowman.net      19331                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              19332                 :              0 :                     tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
                              19333                 :                : 
 3481 peter_e@gmx.net         19334                 :CBC         522 :     free(tag);
 7945 tgl@sss.pgh.pa.us       19335                 :            522 :     destroyPQExpBuffer(query);
                              19336                 :            522 :     destroyPQExpBuffer(delqry);
 2749                         19337                 :            522 :     destroyPQExpBuffer(trigprefix);
 2005 alvherre@alvh.no-ip.    19338                 :            522 :     destroyPQExpBuffer(trigidentity);
 2749 tgl@sss.pgh.pa.us       19339                 :            522 :     free(qtabname);
                              19340                 :                : }
                              19341                 :                : 
                              19342                 :                : /*
                              19343                 :                :  * dumpEventTrigger
                              19344                 :                :  *    write the declaration of one user-defined event trigger
                              19345                 :                :  */
                              19346                 :                : static void
 1669 peter@eisentraut.org    19347                 :             48 : dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
                              19348                 :                : {
 3524 tgl@sss.pgh.pa.us       19349                 :             48 :     DumpOptions *dopt = fout->dopt;
                              19350                 :                :     PQExpBuffer query;
                              19351                 :                :     PQExpBuffer delqry;
                              19352                 :                :     char       *qevtname;
                              19353                 :                : 
                              19354                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    19355         [ +  + ]:             48 :     if (!dopt->dumpSchema)
 4268 tgl@sss.pgh.pa.us       19356                 :              6 :         return;
                              19357                 :                : 
 4798 rhaas@postgresql.org    19358                 :             42 :     query = createPQExpBuffer();
 2968 tgl@sss.pgh.pa.us       19359                 :             42 :     delqry = createPQExpBuffer();
                              19360                 :                : 
 2749                         19361                 :             42 :     qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
                              19362                 :                : 
 4310 heikki.linnakangas@i    19363                 :             42 :     appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
 2749 tgl@sss.pgh.pa.us       19364                 :             42 :     appendPQExpBufferStr(query, qevtname);
 4310 heikki.linnakangas@i    19365                 :             42 :     appendPQExpBufferStr(query, " ON ");
 4798 rhaas@postgresql.org    19366                 :             42 :     appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
                              19367                 :                : 
                              19368         [ +  + ]:             42 :     if (strcmp("", evtinfo->evttags) != 0)
                              19369                 :                :     {
                              19370                 :              5 :         appendPQExpBufferStr(query, "\n         WHEN TAG IN (");
                              19371                 :              5 :         appendPQExpBufferStr(query, evtinfo->evttags);
 3719 heikki.linnakangas@i    19372                 :              5 :         appendPQExpBufferChar(query, ')');
                              19373                 :                :     }
                              19374                 :                : 
 2403 peter@eisentraut.org    19375                 :             42 :     appendPQExpBufferStr(query, "\n   EXECUTE FUNCTION ");
 4798 rhaas@postgresql.org    19376                 :             42 :     appendPQExpBufferStr(query, evtinfo->evtfname);
 4310 heikki.linnakangas@i    19377                 :             42 :     appendPQExpBufferStr(query, "();\n");
                              19378                 :                : 
 4798 rhaas@postgresql.org    19379         [ -  + ]:             42 :     if (evtinfo->evtenabled != 'O')
                              19380                 :                :     {
 4798 rhaas@postgresql.org    19381                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
                              19382                 :                :                           qevtname);
                              19383   [ #  #  #  # ]:              0 :         switch (evtinfo->evtenabled)
                              19384                 :                :         {
                              19385                 :              0 :             case 'D':
 4310 heikki.linnakangas@i    19386                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 4798 rhaas@postgresql.org    19387                 :              0 :                 break;
                              19388                 :              0 :             case 'A':
 4310 heikki.linnakangas@i    19389                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 4798 rhaas@postgresql.org    19390                 :              0 :                 break;
                              19391                 :              0 :             case 'R':
 4310 heikki.linnakangas@i    19392                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 4798 rhaas@postgresql.org    19393                 :              0 :                 break;
                              19394                 :              0 :             default:
 4310 heikki.linnakangas@i    19395                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 4798 rhaas@postgresql.org    19396                 :              0 :                 break;
                              19397                 :                :         }
 4310 heikki.linnakangas@i    19398                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              19399                 :                :     }
                              19400                 :                : 
 2968 tgl@sss.pgh.pa.us       19401                 :CBC          42 :     appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
                              19402                 :                :                       qevtname);
                              19403                 :                : 
 2587                         19404         [ +  + ]:             42 :     if (dopt->binary_upgrade)
                              19405                 :              2 :         binary_upgrade_extension_member(query, &evtinfo->dobj,
                              19406                 :                :                                         "EVENT TRIGGER", qevtname, NULL);
                              19407                 :                : 
 3440 sfrost@snowman.net      19408         [ +  - ]:             42 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19409                 :             42 :         ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    19410                 :             42 :                      ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
                              19411                 :                :                                   .owner = evtinfo->evtowner,
                              19412                 :                :                                   .description = "EVENT TRIGGER",
                              19413                 :                :                                   .section = SECTION_POST_DATA,
                              19414                 :                :                                   .createStmt = query->data,
                              19415                 :                :                                   .dropStmt = delqry->data));
                              19416                 :                : 
 3440 sfrost@snowman.net      19417         [ -  + ]:             42 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       19418                 :UBC           0 :         dumpComment(fout, "EVENT TRIGGER", qevtname,
 3440 sfrost@snowman.net      19419                 :              0 :                     NULL, evtinfo->evtowner,
                              19420                 :              0 :                     evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
                              19421                 :                : 
 4798 rhaas@postgresql.org    19422                 :CBC          42 :     destroyPQExpBuffer(query);
 2968 tgl@sss.pgh.pa.us       19423                 :             42 :     destroyPQExpBuffer(delqry);
 2749                         19424                 :             42 :     free(qevtname);
                              19425                 :                : }
                              19426                 :                : 
                              19427                 :                : /*
                              19428                 :                :  * dumpRule
                              19429                 :                :  *      Dump a rule
                              19430                 :                :  */
                              19431                 :                : static void
 1669 peter@eisentraut.org    19432                 :           1223 : dumpRule(Archive *fout, const RuleInfo *rinfo)
                              19433                 :                : {
 3524 tgl@sss.pgh.pa.us       19434                 :           1223 :     DumpOptions *dopt = fout->dopt;
 7945                         19435                 :           1223 :     TableInfo  *tbinfo = rinfo->ruletable;
                              19436                 :                :     bool        is_view;
                              19437                 :                :     PQExpBuffer query;
                              19438                 :                :     PQExpBuffer cmd;
                              19439                 :                :     PQExpBuffer delcmd;
                              19440                 :                :     PQExpBuffer ruleprefix;
                              19441                 :                :     char       *qtabname;
                              19442                 :                :     PGresult   *res;
                              19443                 :                :     char       *tag;
                              19444                 :                : 
                              19445                 :                :     /* Do nothing if not dumping schema */
  285 nathan@postgresql.or    19446         [ +  + ]:           1223 :     if (!dopt->dumpSchema)
 7945 tgl@sss.pgh.pa.us       19447                 :             66 :         return;
                              19448                 :                : 
                              19449                 :                :     /*
                              19450                 :                :      * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
                              19451                 :                :      * we do not want to dump it as a separate object.
                              19452                 :                :      */
 7571                         19453         [ +  + ]:           1157 :     if (!rinfo->separate)
 7945                         19454                 :            946 :         return;
                              19455                 :                : 
                              19456                 :                :     /*
                              19457                 :                :      * If it's an ON SELECT rule, we want to print it as a view definition,
                              19458                 :                :      * instead of a rule.
                              19459                 :                :      */
 3215                         19460   [ +  +  +  - ]:            211 :     is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
                              19461                 :                : 
 7945                         19462                 :            211 :     query = createPQExpBuffer();
                              19463                 :            211 :     cmd = createPQExpBuffer();
                              19464                 :            211 :     delcmd = createPQExpBuffer();
 2749                         19465                 :            211 :     ruleprefix = createPQExpBuffer();
                              19466                 :                : 
                              19467                 :            211 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              19468                 :                : 
 3215                         19469         [ +  + ]:            211 :     if (is_view)
                              19470                 :                :     {
                              19471                 :                :         PQExpBuffer result;
                              19472                 :                : 
                              19473                 :                :         /*
                              19474                 :                :          * We need OR REPLACE here because we'll be replacing a dummy view.
                              19475                 :                :          * Otherwise this should look largely like the regular view dump code.
                              19476                 :                :          */
                              19477                 :             10 :         appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
 2749                         19478                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 3215                         19479         [ -  + ]:             10 :         if (nonemptyReloptions(tbinfo->reloptions))
                              19480                 :                :         {
 3215 tgl@sss.pgh.pa.us       19481                 :UBC           0 :             appendPQExpBufferStr(cmd, " WITH (");
                              19482                 :              0 :             appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
                              19483                 :              0 :             appendPQExpBufferChar(cmd, ')');
                              19484                 :                :         }
 3215 tgl@sss.pgh.pa.us       19485                 :CBC          10 :         result = createViewAsClause(fout, tbinfo);
                              19486                 :             10 :         appendPQExpBuffer(cmd, " AS\n%s", result->data);
                              19487                 :             10 :         destroyPQExpBuffer(result);
                              19488         [ -  + ]:             10 :         if (tbinfo->checkoption != NULL)
 3215 tgl@sss.pgh.pa.us       19489                 :UBC           0 :             appendPQExpBuffer(cmd, "\n  WITH %s CHECK OPTION",
                              19490                 :                :                               tbinfo->checkoption);
 3215 tgl@sss.pgh.pa.us       19491                 :CBC          10 :         appendPQExpBufferStr(cmd, ";\n");
                              19492                 :                :     }
                              19493                 :                :     else
                              19494                 :                :     {
                              19495                 :                :         /* In the rule case, just print pg_get_ruledef's result verbatim */
                              19496                 :            201 :         appendPQExpBuffer(query,
                              19497                 :                :                           "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
                              19498                 :            201 :                           rinfo->dobj.catId.oid);
                              19499                 :                : 
                              19500                 :            201 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19501                 :                : 
                              19502         [ -  + ]:            201 :         if (PQntuples(res) != 1)
 1247 tgl@sss.pgh.pa.us       19503                 :UBC           0 :             pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
                              19504                 :                :                      rinfo->dobj.name, tbinfo->dobj.name);
                              19505                 :                : 
 3215 tgl@sss.pgh.pa.us       19506                 :CBC         201 :         printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
                              19507                 :                : 
                              19508                 :            201 :         PQclear(res);
                              19509                 :                :     }
                              19510                 :                : 
                              19511                 :                :     /*
                              19512                 :                :      * Add the command to alter the rules replication firing semantics if it
                              19513                 :                :      * differs from the default.
                              19514                 :                :      */
 6746 JanWieck@Yahoo.com      19515         [ +  + ]:            211 :     if (rinfo->ev_enabled != 'O')
                              19516                 :                :     {
 2749 tgl@sss.pgh.pa.us       19517                 :             15 :         appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
 6746 JanWieck@Yahoo.com      19518   [ -  -  +  - ]:             15 :         switch (rinfo->ev_enabled)
                              19519                 :                :         {
 6746 JanWieck@Yahoo.com      19520                 :UBC           0 :             case 'A':
                              19521                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
 6505 bruce@momjian.us        19522                 :              0 :                                   fmtId(rinfo->dobj.name));
 6746 JanWieck@Yahoo.com      19523                 :              0 :                 break;
                              19524                 :              0 :             case 'R':
                              19525                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
 6505 bruce@momjian.us        19526                 :              0 :                                   fmtId(rinfo->dobj.name));
 6746 JanWieck@Yahoo.com      19527                 :              0 :                 break;
 6746 JanWieck@Yahoo.com      19528                 :CBC          15 :             case 'D':
                              19529                 :             15 :                 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
 6505 bruce@momjian.us        19530                 :             15 :                                   fmtId(rinfo->dobj.name));
 6746 JanWieck@Yahoo.com      19531                 :             15 :                 break;
                              19532                 :                :         }
                              19533                 :                :     }
                              19534                 :                : 
 3215 tgl@sss.pgh.pa.us       19535         [ +  + ]:            211 :     if (is_view)
                              19536                 :                :     {
                              19537                 :                :         /*
                              19538                 :                :          * We can't DROP a view's ON SELECT rule.  Instead, use CREATE OR
                              19539                 :                :          * REPLACE VIEW to replace the rule with something with minimal
                              19540                 :                :          * dependencies.
                              19541                 :                :          */
                              19542                 :                :         PQExpBuffer result;
                              19543                 :                : 
 2749                         19544                 :             10 :         appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
                              19545                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 3215                         19546                 :             10 :         result = createDummyViewAsClause(fout, tbinfo);
                              19547                 :             10 :         appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
                              19548                 :             10 :         destroyPQExpBuffer(result);
                              19549                 :                :     }
                              19550                 :                :     else
                              19551                 :                :     {
                              19552                 :            201 :         appendPQExpBuffer(delcmd, "DROP RULE %s ",
                              19553                 :            201 :                           fmtId(rinfo->dobj.name));
 2749                         19554                 :            201 :         appendPQExpBuffer(delcmd, "ON %s;\n",
                              19555                 :            201 :                           fmtQualifiedDumpable(tbinfo));
                              19556                 :                :     }
                              19557                 :                : 
                              19558                 :            211 :     appendPQExpBuffer(ruleprefix, "RULE %s ON",
 5323                         19559                 :            211 :                       fmtId(rinfo->dobj.name));
                              19560                 :                : 
 3481 peter_e@gmx.net         19561                 :            211 :     tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
                              19562                 :                : 
 3440 sfrost@snowman.net      19563         [ +  - ]:            211 :     if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              19564                 :            211 :         ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
 2409 alvherre@alvh.no-ip.    19565                 :            211 :                      ARCHIVE_OPTS(.tag = tag,
                              19566                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              19567                 :                :                                   .owner = tbinfo->rolname,
                              19568                 :                :                                   .description = "RULE",
                              19569                 :                :                                   .section = SECTION_POST_DATA,
                              19570                 :                :                                   .createStmt = cmd->data,
                              19571                 :                :                                   .dropStmt = delcmd->data));
                              19572                 :                : 
                              19573                 :                :     /* Dump rule comments */
 3440 sfrost@snowman.net      19574         [ -  + ]:            211 :     if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2749 tgl@sss.pgh.pa.us       19575                 :UBC           0 :         dumpComment(fout, ruleprefix->data, qtabname,
 3440 sfrost@snowman.net      19576                 :              0 :                     tbinfo->dobj.namespace->dobj.name,
                              19577                 :                :                     tbinfo->rolname,
                              19578                 :              0 :                     rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
                              19579                 :                : 
 3481 peter_e@gmx.net         19580                 :CBC         211 :     free(tag);
 8520 tgl@sss.pgh.pa.us       19581                 :            211 :     destroyPQExpBuffer(query);
 7945                         19582                 :            211 :     destroyPQExpBuffer(cmd);
                              19583                 :            211 :     destroyPQExpBuffer(delcmd);
 2749                         19584                 :            211 :     destroyPQExpBuffer(ruleprefix);
                              19585                 :            211 :     free(qtabname);
                              19586                 :                : }
                              19587                 :                : 
                              19588                 :                : /*
                              19589                 :                :  * getExtensionMembership --- obtain extension membership data
                              19590                 :                :  *
                              19591                 :                :  * We need to identify objects that are extension members as soon as they're
                              19592                 :                :  * loaded, so that we can correctly determine whether they need to be dumped.
                              19593                 :                :  * Generally speaking, extension member objects will get marked as *not* to
                              19594                 :                :  * be dumped, as they will be recreated by the single CREATE EXTENSION
                              19595                 :                :  * command.  However, in binary upgrade mode we still need to dump the members
                              19596                 :                :  * individually.
                              19597                 :                :  */
                              19598                 :                : void
 3524                         19599                 :            186 : getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                              19600                 :                :                        int numExtensions)
                              19601                 :                : {
                              19602                 :                :     PQExpBuffer query;
                              19603                 :                :     PGresult   *res;
                              19604                 :                :     int         ntups,
                              19605                 :                :                 i;
                              19606                 :                :     int         i_classid,
                              19607                 :                :                 i_objid,
                              19608                 :                :                 i_refobjid;
                              19609                 :                :     ExtensionInfo *ext;
                              19610                 :                : 
                              19611                 :                :     /* Nothing to do if no extensions */
 5323                         19612         [ -  + ]:            186 :     if (numExtensions == 0)
 5323 tgl@sss.pgh.pa.us       19613                 :UBC           0 :         return;
                              19614                 :                : 
 5323 tgl@sss.pgh.pa.us       19615                 :CBC         186 :     query = createPQExpBuffer();
                              19616                 :                : 
                              19617                 :                :     /* refclassid constraint is redundant but may speed the search */
 4310 heikki.linnakangas@i    19618                 :            186 :     appendPQExpBufferStr(query, "SELECT "
                              19619                 :                :                          "classid, objid, refobjid "
                              19620                 :                :                          "FROM pg_depend "
                              19621                 :                :                          "WHERE refclassid = 'pg_extension'::regclass "
                              19622                 :                :                          "AND deptype = 'e' "
                              19623                 :                :                          "ORDER BY 3");
                              19624                 :                : 
 4960 rhaas@postgresql.org    19625                 :            186 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19626                 :                : 
 5323 tgl@sss.pgh.pa.us       19627                 :            186 :     ntups = PQntuples(res);
                              19628                 :                : 
                              19629                 :            186 :     i_classid = PQfnumber(res, "classid");
                              19630                 :            186 :     i_objid = PQfnumber(res, "objid");
                              19631                 :            186 :     i_refobjid = PQfnumber(res, "refobjid");
                              19632                 :                : 
                              19633                 :                :     /*
                              19634                 :                :      * Since we ordered the SELECT by referenced ID, we can expect that
                              19635                 :                :      * multiple entries for the same extension will appear together; this
                              19636                 :                :      * saves on searches.
                              19637                 :                :      */
 3524                         19638                 :            186 :     ext = NULL;
                              19639                 :                : 
 5323                         19640         [ +  + ]:           1530 :     for (i = 0; i < ntups; i++)
                              19641                 :                :     {
                              19642                 :                :         CatalogId   objId;
                              19643                 :                :         Oid         extId;
                              19644                 :                : 
                              19645                 :           1344 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              19646                 :           1344 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
 3524                         19647                 :           1344 :         extId = atooid(PQgetvalue(res, i, i_refobjid));
                              19648                 :                : 
                              19649         [ +  + ]:           1344 :         if (ext == NULL ||
                              19650         [ +  + ]:           1158 :             ext->dobj.catId.oid != extId)
                              19651                 :            211 :             ext = findExtensionByOid(extId);
                              19652                 :                : 
                              19653         [ -  + ]:           1344 :         if (ext == NULL)
                              19654                 :                :         {
                              19655                 :                :             /* shouldn't happen */
 2350 peter@eisentraut.org    19656                 :UBC           0 :             pg_log_warning("could not find referenced extension %u", extId);
 5323 tgl@sss.pgh.pa.us       19657                 :              0 :             continue;
                              19658                 :                :         }
                              19659                 :                : 
 1415 tgl@sss.pgh.pa.us       19660                 :CBC        1344 :         recordExtensionMembership(objId, ext);
                              19661                 :                :     }
                              19662                 :                : 
 3524                         19663                 :            186 :     PQclear(res);
                              19664                 :                : 
                              19665                 :            186 :     destroyPQExpBuffer(query);
                              19666                 :                : }
                              19667                 :                : 
                              19668                 :                : /*
                              19669                 :                :  * processExtensionTables --- deal with extension configuration tables
                              19670                 :                :  *
                              19671                 :                :  * There are two parts to this process:
                              19672                 :                :  *
                              19673                 :                :  * 1. Identify and create dump records for extension configuration tables.
                              19674                 :                :  *
                              19675                 :                :  *    Extensions can mark tables as "configuration", which means that the user
                              19676                 :                :  *    is able and expected to modify those tables after the extension has been
                              19677                 :                :  *    loaded.  For these tables, we dump out only the data- the structure is
                              19678                 :                :  *    expected to be handled at CREATE EXTENSION time, including any indexes or
                              19679                 :                :  *    foreign keys, which brings us to-
                              19680                 :                :  *
                              19681                 :                :  * 2. Record FK dependencies between configuration tables.
                              19682                 :                :  *
                              19683                 :                :  *    Due to the FKs being created at CREATE EXTENSION time and therefore before
                              19684                 :                :  *    the data is loaded, we have to work out what the best order for reloading
                              19685                 :                :  *    the data is, to avoid FK violations when the tables are restored.  This is
                              19686                 :                :  *    not perfect- we can't handle circular dependencies and if any exist they
                              19687                 :                :  *    will cause an invalid dump to be produced (though at least all of the data
                              19688                 :                :  *    is included for a user to manually restore).  This is currently documented
                              19689                 :                :  *    but perhaps we can provide a better solution in the future.
                              19690                 :                :  */
                              19691                 :                : void
                              19692                 :            185 : processExtensionTables(Archive *fout, ExtensionInfo extinfo[],
                              19693                 :                :                        int numExtensions)
                              19694                 :                : {
                              19695                 :            185 :     DumpOptions *dopt = fout->dopt;
                              19696                 :                :     PQExpBuffer query;
                              19697                 :                :     PGresult   *res;
                              19698                 :                :     int         ntups,
                              19699                 :                :                 i;
                              19700                 :                :     int         i_conrelid,
                              19701                 :                :                 i_confrelid;
                              19702                 :                : 
                              19703                 :                :     /* Nothing to do if no extensions */
                              19704         [ -  + ]:            185 :     if (numExtensions == 0)
 3524 tgl@sss.pgh.pa.us       19705                 :UBC           0 :         return;
                              19706                 :                : 
                              19707                 :                :     /*
                              19708                 :                :      * Identify extension configuration tables and create TableDataInfo
                              19709                 :                :      * objects for them, ensuring their data will be dumped even though the
                              19710                 :                :      * tables themselves won't be.
                              19711                 :                :      *
                              19712                 :                :      * Note that we create TableDataInfo objects even in schema-only mode, ie,
                              19713                 :                :      * user data in a configuration table is treated like schema data. This
                              19714                 :                :      * seems appropriate since system data in a config table would get
                              19715                 :                :      * reloaded by CREATE EXTENSION.  If the extension is not listed in the
                              19716                 :                :      * list of extensions to be included, none of its data is dumped.
                              19717                 :                :      */
 5323 tgl@sss.pgh.pa.us       19718         [ +  + ]:CBC         395 :     for (i = 0; i < numExtensions; i++)
                              19719                 :                :     {
 4957                         19720                 :            210 :         ExtensionInfo *curext = &(extinfo[i]);
                              19721                 :            210 :         char       *extconfig = curext->extconfig;
                              19722                 :            210 :         char       *extcondition = curext->extcondition;
 5263 bruce@momjian.us        19723                 :            210 :         char      **extconfigarray = NULL;
                              19724                 :            210 :         char      **extconditionarray = NULL;
 1752 michael@paquier.xyz     19725                 :            210 :         int         nconfigitems = 0;
                              19726                 :            210 :         int         nconditionitems = 0;
                              19727                 :                : 
                              19728                 :                :         /*
                              19729                 :                :          * Check if this extension is listed as to include in the dump.  If
                              19730                 :                :          * not, any table data associated with it is discarded.
                              19731                 :                :          */
 1605                         19732         [ +  + ]:            210 :         if (extension_include_oids.head != NULL &&
                              19733         [ +  + ]:              8 :             !simple_oid_list_member(&extension_include_oids,
                              19734                 :                :                                     curext->dobj.catId.oid))
                              19735                 :              6 :             continue;
                              19736                 :                : 
                              19737                 :                :         /*
                              19738                 :                :          * Check if this extension is listed as to exclude in the dump.  If
                              19739                 :                :          * yes, any table data associated with it is discarded.
                              19740                 :                :          */
  535 dean.a.rasheed@gmail    19741   [ +  +  +  + ]:            210 :         if (extension_exclude_oids.head != NULL &&
                              19742                 :              4 :             simple_oid_list_member(&extension_exclude_oids,
                              19743                 :                :                                    curext->dobj.catId.oid))
                              19744                 :              2 :             continue;
                              19745                 :                : 
 1752 michael@paquier.xyz     19746   [ +  +  -  + ]:            204 :         if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
                              19747                 :                :         {
                              19748                 :                :             int         j;
                              19749                 :                : 
                              19750         [ -  + ]:             20 :             if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
 1247 tgl@sss.pgh.pa.us       19751                 :UBC           0 :                 pg_fatal("could not parse %s array", "extconfig");
 1752 michael@paquier.xyz     19752         [ -  + ]:CBC          20 :             if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
 1247 tgl@sss.pgh.pa.us       19753                 :UBC           0 :                 pg_fatal("could not parse %s array", "extcondition");
 1752 michael@paquier.xyz     19754         [ -  + ]:CBC          20 :             if (nconfigitems != nconditionitems)
 1247 tgl@sss.pgh.pa.us       19755                 :UBC           0 :                 pg_fatal("mismatched number of configurations and conditions for extension");
                              19756                 :                : 
 5323 tgl@sss.pgh.pa.us       19757         [ +  + ]:CBC          60 :             for (j = 0; j < nconfigitems; j++)
                              19758                 :                :             {
                              19759                 :                :                 TableInfo  *configtbl;
 4516 mail@joeconway.com      19760                 :             40 :                 Oid         configtbloid = atooid(extconfigarray[j]);
 3440 sfrost@snowman.net      19761                 :             40 :                 bool        dumpobj =
  841 tgl@sss.pgh.pa.us       19762                 :             40 :                     curext->dobj.dump & DUMP_COMPONENT_DEFINITION;
                              19763                 :                : 
 4516 mail@joeconway.com      19764                 :             40 :                 configtbl = findTableByOid(configtbloid);
 4959 tgl@sss.pgh.pa.us       19765         [ -  + ]:             40 :                 if (configtbl == NULL)
 4959 tgl@sss.pgh.pa.us       19766                 :UBC           0 :                     continue;
                              19767                 :                : 
                              19768                 :                :                 /*
                              19769                 :                :                  * Tables of not-to-be-dumped extensions shouldn't be dumped
                              19770                 :                :                  * unless the table or its schema is explicitly included
                              19771                 :                :                  */
 3440 sfrost@snowman.net      19772         [ +  + ]:CBC          40 :                 if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
                              19773                 :                :                 {
                              19774                 :                :                     /* check table explicitly requested */
 4516 mail@joeconway.com      19775   [ -  +  -  - ]:              2 :                     if (table_include_oids.head != NULL &&
 4516 mail@joeconway.com      19776                 :UBC           0 :                         simple_oid_list_member(&table_include_oids,
                              19777                 :                :                                                configtbloid))
                              19778                 :              0 :                         dumpobj = true;
                              19779                 :                : 
                              19780                 :                :                     /* check table's schema explicitly requested */
 3440 sfrost@snowman.net      19781         [ +  - ]:CBC           2 :                     if (configtbl->dobj.namespace->dobj.dump &
                              19782                 :                :                         DUMP_COMPONENT_DATA)
 4516 mail@joeconway.com      19783                 :              2 :                         dumpobj = true;
                              19784                 :                :                 }
                              19785                 :                : 
                              19786                 :                :                 /* check table excluded by an exclusion switch */
                              19787   [ +  +  +  + ]:             44 :                 if (table_exclude_oids.head != NULL &&
                              19788                 :              4 :                     simple_oid_list_member(&table_exclude_oids,
                              19789                 :                :                                            configtbloid))
                              19790                 :              1 :                     dumpobj = false;
                              19791                 :                : 
                              19792                 :                :                 /* check schema excluded by an exclusion switch */
                              19793         [ -  + ]:             40 :                 if (simple_oid_list_member(&schema_exclude_oids,
 2999 tgl@sss.pgh.pa.us       19794                 :             40 :                                            configtbl->dobj.namespace->dobj.catId.oid))
 4516 mail@joeconway.com      19795                 :UBC           0 :                     dumpobj = false;
                              19796                 :                : 
 4516 mail@joeconway.com      19797         [ +  + ]:CBC          40 :                 if (dumpobj)
                              19798                 :                :                 {
 2482 andres@anarazel.de      19799                 :             39 :                     makeTableDataInfo(dopt, configtbl);
 4516 mail@joeconway.com      19800         [ +  - ]:             39 :                     if (configtbl->dataObj != NULL)
                              19801                 :                :                     {
                              19802         [ -  + ]:             39 :                         if (strlen(extconditionarray[j]) > 0)
 4516 mail@joeconway.com      19803                 :UBC           0 :                             configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
                              19804                 :                :                     }
                              19805                 :                :                 }
                              19806                 :                :             }
                              19807                 :                :         }
 5323 tgl@sss.pgh.pa.us       19808         [ +  + ]:CBC         204 :         if (extconfigarray)
                              19809                 :             20 :             free(extconfigarray);
                              19810         [ +  + ]:            204 :         if (extconditionarray)
                              19811                 :             20 :             free(extconditionarray);
                              19812                 :                :     }
                              19813                 :                : 
                              19814                 :                :     /*
                              19815                 :                :      * Now that all the TableDataInfo objects have been created for all the
                              19816                 :                :      * extensions, check their FK dependencies and register them to try and
                              19817                 :                :      * dump the data out in an order that they can be restored in.
                              19818                 :                :      *
                              19819                 :                :      * Note that this is not a problem for user tables as their FKs are
                              19820                 :                :      * recreated after the data has been loaded.
                              19821                 :                :      */
                              19822                 :                : 
 3524                         19823                 :            185 :     query = createPQExpBuffer();
                              19824                 :                : 
 3841 sfrost@snowman.net      19825                 :            185 :     printfPQExpBuffer(query,
                              19826                 :                :                       "SELECT conrelid, confrelid "
                              19827                 :                :                       "FROM pg_constraint "
                              19828                 :                :                       "JOIN pg_depend ON (objid = confrelid) "
                              19829                 :                :                       "WHERE contype = 'f' "
                              19830                 :                :                       "AND refclassid = 'pg_extension'::regclass "
                              19831                 :                :                       "AND classid = 'pg_class'::regclass;");
                              19832                 :                : 
                              19833                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19834                 :            185 :     ntups = PQntuples(res);
                              19835                 :                : 
                              19836                 :            185 :     i_conrelid = PQfnumber(res, "conrelid");
                              19837                 :            185 :     i_confrelid = PQfnumber(res, "confrelid");
                              19838                 :                : 
                              19839                 :                :     /* Now get the dependencies and register them */
                              19840         [ -  + ]:            185 :     for (i = 0; i < ntups; i++)
                              19841                 :                :     {
                              19842                 :                :         Oid         conrelid,
                              19843                 :                :                     confrelid;
                              19844                 :                :         TableInfo  *reftable,
                              19845                 :                :                    *contable;
                              19846                 :                : 
 3841 sfrost@snowman.net      19847                 :UBC           0 :         conrelid = atooid(PQgetvalue(res, i, i_conrelid));
                              19848                 :              0 :         confrelid = atooid(PQgetvalue(res, i, i_confrelid));
                              19849                 :              0 :         contable = findTableByOid(conrelid);
                              19850                 :              0 :         reftable = findTableByOid(confrelid);
                              19851                 :                : 
                              19852         [ #  # ]:              0 :         if (reftable == NULL ||
                              19853   [ #  #  #  # ]:              0 :             reftable->dataObj == NULL ||
                              19854                 :              0 :             contable == NULL ||
                              19855         [ #  # ]:              0 :             contable->dataObj == NULL)
                              19856                 :              0 :             continue;
                              19857                 :                : 
                              19858                 :                :         /*
                              19859                 :                :          * Make referencing TABLE_DATA object depend on the referenced table's
                              19860                 :                :          * TABLE_DATA object.
                              19861                 :                :          */
                              19862                 :              0 :         addObjectDependency(&contable->dataObj->dobj,
                              19863                 :              0 :                             reftable->dataObj->dobj.dumpId);
                              19864                 :                :     }
 3709 tgl@sss.pgh.pa.us       19865                 :CBC         185 :     PQclear(res);
 5323                         19866                 :            185 :     destroyPQExpBuffer(query);
                              19867                 :                : }
                              19868                 :                : 
                              19869                 :                : /*
                              19870                 :                :  * getDependencies --- obtain available dependency data
                              19871                 :                :  */
                              19872                 :                : static void
 4961 rhaas@postgresql.org    19873                 :            185 : getDependencies(Archive *fout)
                              19874                 :                : {
                              19875                 :                :     PQExpBuffer query;
                              19876                 :                :     PGresult   *res;
                              19877                 :                :     int         ntups,
                              19878                 :                :                 i;
                              19879                 :                :     int         i_classid,
                              19880                 :                :                 i_objid,
                              19881                 :                :                 i_refclassid,
                              19882                 :                :                 i_refobjid,
                              19883                 :                :                 i_deptype;
                              19884                 :                :     DumpableObject *dobj,
                              19885                 :                :                *refdobj;
                              19886                 :                : 
 2350 peter@eisentraut.org    19887                 :            185 :     pg_log_info("reading dependency data");
                              19888                 :                : 
 7945 tgl@sss.pgh.pa.us       19889                 :            185 :     query = createPQExpBuffer();
                              19890                 :                : 
                              19891                 :                :     /*
                              19892                 :                :      * Messy query to collect the dependency data we need.  Note that we
                              19893                 :                :      * ignore the sub-object column, so that dependencies of or on a column
                              19894                 :                :      * look the same as dependencies of or on a whole table.
                              19895                 :                :      *
                              19896                 :                :      * PIN dependencies aren't interesting, and EXTENSION dependencies were
                              19897                 :                :      * already processed by getExtensionMembership.
                              19898                 :                :      */
 4310 heikki.linnakangas@i    19899                 :            185 :     appendPQExpBufferStr(query, "SELECT "
                              19900                 :                :                          "classid, objid, refclassid, refobjid, deptype "
                              19901                 :                :                          "FROM pg_depend "
                              19902                 :                :                          "WHERE deptype != 'p' AND deptype != 'e'\n");
                              19903                 :                : 
                              19904                 :                :     /*
                              19905                 :                :      * Since we don't treat pg_amop entries as separate DumpableObjects, we
                              19906                 :                :      * have to translate their dependencies into dependencies of their parent
                              19907                 :                :      * opfamily.  Ignore internal dependencies though, as those will point to
                              19908                 :                :      * their parent opclass, which we needn't consider here (and if we did,
                              19909                 :                :      * it'd just result in circular dependencies).  Also, "loose" opfamily
                              19910                 :                :      * entries will have dependencies on their parent opfamily, which we
                              19911                 :                :      * should drop since they'd likewise become useless self-dependencies.
                              19912                 :                :      * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
                              19913                 :                :      */
 1362 tgl@sss.pgh.pa.us       19914                 :            185 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              19915                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
                              19916                 :                :                          "FROM pg_depend d, pg_amop o "
                              19917                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              19918                 :                :                          "classid = 'pg_amop'::regclass AND objid = o.oid "
                              19919                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
                              19920                 :                : 
                              19921                 :                :     /* Likewise for pg_amproc entries */
                              19922                 :            185 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              19923                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
                              19924                 :                :                          "FROM pg_depend d, pg_amproc p "
                              19925                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              19926                 :                :                          "classid = 'pg_amproc'::regclass AND objid = p.oid "
                              19927                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
                              19928                 :                : 
                              19929                 :                :     /* Sort the output for efficiency below */
 2229                         19930                 :            185 :     appendPQExpBufferStr(query, "ORDER BY 1,2");
                              19931                 :                : 
 4960 rhaas@postgresql.org    19932                 :            185 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              19933                 :                : 
 7945 tgl@sss.pgh.pa.us       19934                 :            185 :     ntups = PQntuples(res);
                              19935                 :                : 
                              19936                 :            185 :     i_classid = PQfnumber(res, "classid");
                              19937                 :            185 :     i_objid = PQfnumber(res, "objid");
                              19938                 :            185 :     i_refclassid = PQfnumber(res, "refclassid");
                              19939                 :            185 :     i_refobjid = PQfnumber(res, "refobjid");
                              19940                 :            185 :     i_deptype = PQfnumber(res, "deptype");
                              19941                 :                : 
                              19942                 :                :     /*
                              19943                 :                :      * Since we ordered the SELECT by referencing ID, we can expect that
                              19944                 :                :      * multiple entries for the same object will appear together; this saves
                              19945                 :                :      * on searches.
                              19946                 :                :      */
                              19947                 :            185 :     dobj = NULL;
                              19948                 :                : 
                              19949         [ +  + ]:         402500 :     for (i = 0; i < ntups; i++)
                              19950                 :                :     {
                              19951                 :                :         CatalogId   objId;
                              19952                 :                :         CatalogId   refobjId;
                              19953                 :                :         char        deptype;
                              19954                 :                : 
                              19955                 :         402315 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              19956                 :         402315 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                              19957                 :         402315 :         refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
                              19958                 :         402315 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                              19959                 :         402315 :         deptype = *(PQgetvalue(res, i, i_deptype));
                              19960                 :                : 
                              19961         [ +  + ]:         402315 :         if (dobj == NULL ||
                              19962         [ +  + ]:         376636 :             dobj->catId.tableoid != objId.tableoid ||
                              19963         [ +  + ]:         374445 :             dobj->catId.oid != objId.oid)
                              19964                 :         177586 :             dobj = findObjectByCatalogId(objId);
                              19965                 :                : 
                              19966                 :                :         /*
                              19967                 :                :          * Failure to find objects mentioned in pg_depend is not unexpected,
                              19968                 :                :          * since for example we don't collect info about TOAST tables.
                              19969                 :                :          */
                              19970         [ +  + ]:         402315 :         if (dobj == NULL)
                              19971                 :                :         {
                              19972                 :                : #ifdef NOT_USED
                              19973                 :                :             pg_log_warning("no referencing object %u %u",
                              19974                 :                :                            objId.tableoid, objId.oid);
                              19975                 :                : #endif
                              19976                 :          26343 :             continue;
                              19977                 :                :         }
                              19978                 :                : 
                              19979                 :         376821 :         refdobj = findObjectByCatalogId(refobjId);
                              19980                 :                : 
                              19981         [ +  + ]:         376821 :         if (refdobj == NULL)
                              19982                 :                :         {
                              19983                 :                : #ifdef NOT_USED
                              19984                 :                :             pg_log_warning("no referenced object %u %u",
                              19985                 :                :                            refobjId.tableoid, refobjId.oid);
                              19986                 :                : #endif
                              19987                 :            849 :             continue;
                              19988                 :                :         }
                              19989                 :                : 
                              19990                 :                :         /*
                              19991                 :                :          * For 'x' dependencies, mark the object for later; we still add the
                              19992                 :                :          * normal dependency, for possible ordering purposes.  Currently
                              19993                 :                :          * pg_dump_sort.c knows to put extensions ahead of all object types
                              19994                 :                :          * that could possibly depend on them, but this is safer.
                              19995                 :                :          */
 2005 alvherre@alvh.no-ip.    19996         [ +  + ]:         375972 :         if (deptype == 'x')
                              19997                 :             44 :             dobj->depends_on_ext = true;
                              19998                 :                : 
                              19999                 :                :         /*
                              20000                 :                :          * Ordinarily, table rowtypes have implicit dependencies on their
                              20001                 :                :          * tables.  However, for a composite type the implicit dependency goes
                              20002                 :                :          * the other way in pg_depend; which is the right thing for DROP but
                              20003                 :                :          * it doesn't produce the dependency ordering we need. So in that one
                              20004                 :                :          * case, we reverse the direction of the dependency.
                              20005                 :                :          */
 7543 tgl@sss.pgh.pa.us       20006         [ +  + ]:         375972 :         if (deptype == 'i' &&
                              20007         [ +  + ]:         105925 :             dobj->objType == DO_TABLE &&
                              20008         [ +  + ]:           1280 :             refdobj->objType == DO_TYPE)
                              20009                 :            188 :             addObjectDependency(refdobj, dobj->dumpId);
                              20010                 :                :         else
                              20011                 :                :             /* normal case */
                              20012                 :         375784 :             addObjectDependency(dobj, refdobj->dumpId);
                              20013                 :                :     }
                              20014                 :                : 
 7945                         20015                 :            185 :     PQclear(res);
                              20016                 :                : 
 8800                         20017                 :            185 :     destroyPQExpBuffer(query);
 9832 bruce@momjian.us        20018                 :            185 : }
                              20019                 :                : 
                              20020                 :                : 
                              20021                 :                : /*
                              20022                 :                :  * createBoundaryObjects - create dummy DumpableObjects to represent
                              20023                 :                :  * dump section boundaries.
                              20024                 :                :  */
                              20025                 :                : static DumpableObject *
 4821 tgl@sss.pgh.pa.us       20026                 :            185 : createBoundaryObjects(void)
                              20027                 :                : {
                              20028                 :                :     DumpableObject *dobjs;
                              20029                 :                : 
                              20030                 :            185 :     dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
                              20031                 :                : 
                              20032                 :            185 :     dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
                              20033                 :            185 :     dobjs[0].catId = nilCatalogId;
                              20034                 :            185 :     AssignDumpId(dobjs + 0);
                              20035                 :            185 :     dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
                              20036                 :                : 
                              20037                 :            185 :     dobjs[1].objType = DO_POST_DATA_BOUNDARY;
                              20038                 :            185 :     dobjs[1].catId = nilCatalogId;
                              20039                 :            185 :     AssignDumpId(dobjs + 1);
                              20040                 :            185 :     dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
                              20041                 :                : 
                              20042                 :            185 :     return dobjs;
                              20043                 :                : }
                              20044                 :                : 
                              20045                 :                : /*
                              20046                 :                :  * addBoundaryDependencies - add dependencies as needed to enforce the dump
                              20047                 :                :  * section boundaries.
                              20048                 :                :  */
                              20049                 :                : static void
                              20050                 :            185 : addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
                              20051                 :                :                         DumpableObject *boundaryObjs)
                              20052                 :                : {
                              20053                 :            185 :     DumpableObject *preDataBound = boundaryObjs + 0;
                              20054                 :            185 :     DumpableObject *postDataBound = boundaryObjs + 1;
                              20055                 :                :     int         i;
                              20056                 :                : 
                              20057         [ +  + ]:         819380 :     for (i = 0; i < numObjs; i++)
                              20058                 :                :     {
                              20059                 :         819195 :         DumpableObject *dobj = dobjs[i];
                              20060                 :                : 
                              20061                 :                :         /*
                              20062                 :                :          * The classification of object types here must match the SECTION_xxx
                              20063                 :                :          * values assigned during subsequent ArchiveEntry calls!
                              20064                 :                :          */
                              20065   [ +  +  +  +  :         819195 :         switch (dobj->objType)
                                        +  +  +  +  
                                                 - ]
                              20066                 :                :         {
                              20067                 :         772550 :             case DO_NAMESPACE:
                              20068                 :                :             case DO_EXTENSION:
                              20069                 :                :             case DO_TYPE:
                              20070                 :                :             case DO_SHELL_TYPE:
                              20071                 :                :             case DO_FUNC:
                              20072                 :                :             case DO_AGG:
                              20073                 :                :             case DO_OPERATOR:
                              20074                 :                :             case DO_ACCESS_METHOD:
                              20075                 :                :             case DO_OPCLASS:
                              20076                 :                :             case DO_OPFAMILY:
                              20077                 :                :             case DO_COLLATION:
                              20078                 :                :             case DO_CONVERSION:
                              20079                 :                :             case DO_TABLE:
                              20080                 :                :             case DO_TABLE_ATTACH:
                              20081                 :                :             case DO_ATTRDEF:
                              20082                 :                :             case DO_PROCLANG:
                              20083                 :                :             case DO_CAST:
                              20084                 :                :             case DO_DUMMY_TYPE:
                              20085                 :                :             case DO_TSPARSER:
                              20086                 :                :             case DO_TSDICT:
                              20087                 :                :             case DO_TSTEMPLATE:
                              20088                 :                :             case DO_TSCONFIG:
                              20089                 :                :             case DO_FDW:
                              20090                 :                :             case DO_FOREIGN_SERVER:
                              20091                 :                :             case DO_TRANSFORM:
                              20092                 :                :                 /* Pre-data objects: must come before the pre-data boundary */
                              20093                 :         772550 :                 addObjectDependency(preDataBound, dobj->dumpId);
                              20094                 :         772550 :                 break;
                              20095                 :           5077 :             case DO_TABLE_DATA:
                              20096                 :                :             case DO_SEQUENCE_SET:
                              20097                 :                :             case DO_LARGE_OBJECT:
                              20098                 :                :             case DO_LARGE_OBJECT_DATA:
                              20099                 :                :                 /* Data objects: must come between the boundaries */
                              20100                 :           5077 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              20101                 :           5077 :                 addObjectDependency(postDataBound, dobj->dumpId);
                              20102                 :           5077 :                 break;
                              20103                 :           6090 :             case DO_INDEX:
                              20104                 :                :             case DO_INDEX_ATTACH:
                              20105                 :                :             case DO_STATSEXT:
                              20106                 :                :             case DO_REFRESH_MATVIEW:
                              20107                 :                :             case DO_TRIGGER:
                              20108                 :                :             case DO_EVENT_TRIGGER:
                              20109                 :                :             case DO_DEFAULT_ACL:
                              20110                 :                :             case DO_POLICY:
                              20111                 :                :             case DO_PUBLICATION:
                              20112                 :                :             case DO_PUBLICATION_REL:
                              20113                 :                :             case DO_PUBLICATION_TABLE_IN_SCHEMA:
                              20114                 :                :             case DO_SUBSCRIPTION:
                              20115                 :                :             case DO_SUBSCRIPTION_REL:
                              20116                 :                :                 /* Post-data objects: must come after the post-data boundary */
                              20117                 :           6090 :                 addObjectDependency(dobj, postDataBound->dumpId);
                              20118                 :           6090 :                 break;
                              20119                 :          28627 :             case DO_RULE:
                              20120                 :                :                 /* Rules are post-data, but only if dumped separately */
                              20121         [ +  + ]:          28627 :                 if (((RuleInfo *) dobj)->separate)
                              20122                 :            643 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20123                 :          28627 :                 break;
                              20124                 :           2689 :             case DO_CONSTRAINT:
                              20125                 :                :             case DO_FK_CONSTRAINT:
                              20126                 :                :                 /* Constraints are post-data, but only if dumped separately */
                              20127         [ +  + ]:           2689 :                 if (((ConstraintInfo *) dobj)->separate)
                              20128                 :           1899 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20129                 :           2689 :                 break;
                              20130                 :            185 :             case DO_PRE_DATA_BOUNDARY:
                              20131                 :                :                 /* nothing to do */
                              20132                 :            185 :                 break;
                              20133                 :            185 :             case DO_POST_DATA_BOUNDARY:
                              20134                 :                :                 /* must come after the pre-data boundary */
                              20135                 :            185 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              20136                 :            185 :                 break;
  198 jdavis@postgresql.or    20137                 :           3792 :             case DO_REL_STATS:
                              20138                 :                :                 /* stats section varies by parent object type, DATA or POST */
  162                         20139         [ +  + ]:           3792 :                 if (((RelStatsInfo *) dobj)->section == SECTION_DATA)
                              20140                 :                :                 {
  198                         20141                 :           2422 :                     addObjectDependency(dobj, preDataBound->dumpId);
                              20142                 :           2422 :                     addObjectDependency(postDataBound, dobj->dumpId);
                              20143                 :                :                 }
                              20144                 :                :                 else
                              20145                 :           1370 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              20146                 :           3792 :                 break;
                              20147                 :                :         }
                              20148                 :                :     }
 4821 tgl@sss.pgh.pa.us       20149                 :            185 : }
                              20150                 :                : 
                              20151                 :                : 
                              20152                 :                : /*
                              20153                 :                :  * BuildArchiveDependencies - create dependency data for archive TOC entries
                              20154                 :                :  *
                              20155                 :                :  * The raw dependency data obtained by getDependencies() is not terribly
                              20156                 :                :  * useful in an archive dump, because in many cases there are dependency
                              20157                 :                :  * chains linking through objects that don't appear explicitly in the dump.
                              20158                 :                :  * For example, a view will depend on its _RETURN rule while the _RETURN rule
                              20159                 :                :  * will depend on other objects --- but the rule will not appear as a separate
                              20160                 :                :  * object in the dump.  We need to adjust the view's dependencies to include
                              20161                 :                :  * whatever the rule depends on that is included in the dump.
                              20162                 :                :  *
                              20163                 :                :  * Just to make things more complicated, there are also "special" dependencies
                              20164                 :                :  * such as the dependency of a TABLE DATA item on its TABLE, which we must
                              20165                 :                :  * not rearrange because pg_restore knows that TABLE DATA only depends on
                              20166                 :                :  * its table.  In these cases we must leave the dependencies strictly as-is
                              20167                 :                :  * even if they refer to not-to-be-dumped objects.
                              20168                 :                :  *
                              20169                 :                :  * To handle this, the convention is that "special" dependencies are created
                              20170                 :                :  * during ArchiveEntry calls, and an archive TOC item that has any such
                              20171                 :                :  * entries will not be touched here.  Otherwise, we recursively search the
                              20172                 :                :  * DumpableObject data structures to build the correct dependencies for each
                              20173                 :                :  * archive TOC item.
                              20174                 :                :  */
                              20175                 :                : static void
                              20176                 :             55 : BuildArchiveDependencies(Archive *fout)
                              20177                 :                : {
                              20178                 :             55 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                              20179                 :                :     TocEntry   *te;
                              20180                 :                : 
                              20181                 :                :     /* Scan all TOC entries in the archive */
                              20182         [ +  + ]:           8030 :     for (te = AH->toc->next; te != AH->toc; te = te->next)
                              20183                 :                :     {
                              20184                 :                :         DumpableObject *dobj;
                              20185                 :                :         DumpId     *dependencies;
                              20186                 :                :         int         nDeps;
                              20187                 :                :         int         allocDeps;
                              20188                 :                : 
                              20189                 :                :         /* No need to process entries that will not be dumped */
                              20190         [ +  + ]:           7975 :         if (te->reqs == 0)
                              20191                 :           3971 :             continue;
                              20192                 :                :         /* Ignore entries that already have "special" dependencies */
                              20193         [ +  + ]:           7972 :         if (te->nDeps > 0)
                              20194                 :           3539 :             continue;
                              20195                 :                :         /* Otherwise, look up the item's original DumpableObject, if any */
                              20196                 :           4433 :         dobj = findObjectByDumpId(te->dumpId);
                              20197         [ +  + ]:           4433 :         if (dobj == NULL)
                              20198                 :            301 :             continue;
                              20199                 :                :         /* No work if it has no dependencies */
                              20200         [ +  + ]:           4132 :         if (dobj->nDeps <= 0)
                              20201                 :            128 :             continue;
                              20202                 :                :         /* Set up work array */
                              20203                 :           4004 :         allocDeps = 64;
                              20204                 :           4004 :         dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
                              20205                 :           4004 :         nDeps = 0;
                              20206                 :                :         /* Recursively find all dumpable dependencies */
                              20207                 :           4004 :         findDumpableDependencies(AH, dobj,
                              20208                 :                :                                  &dependencies, &nDeps, &allocDeps);
                              20209                 :                :         /* And save 'em ... */
                              20210         [ +  + ]:           4004 :         if (nDeps > 0)
                              20211                 :                :         {
                              20212                 :           3134 :             dependencies = (DumpId *) pg_realloc(dependencies,
                              20213                 :                :                                                  nDeps * sizeof(DumpId));
                              20214                 :           3134 :             te->dependencies = dependencies;
                              20215                 :           3134 :             te->nDeps = nDeps;
                              20216                 :                :         }
                              20217                 :                :         else
                              20218                 :            870 :             free(dependencies);
                              20219                 :                :     }
                              20220                 :             55 : }
                              20221                 :                : 
                              20222                 :                : /* Recursive search subroutine for BuildArchiveDependencies */
                              20223                 :                : static void
 1669 peter@eisentraut.org    20224                 :           9405 : findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
                              20225                 :                :                          DumpId **dependencies, int *nDeps, int *allocDeps)
                              20226                 :                : {
                              20227                 :                :     int         i;
                              20228                 :                : 
                              20229                 :                :     /*
                              20230                 :                :      * Ignore section boundary objects: if we search through them, we'll
                              20231                 :                :      * report lots of bogus dependencies.
                              20232                 :                :      */
 4821 tgl@sss.pgh.pa.us       20233         [ +  + ]:           9405 :     if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
                              20234         [ +  + ]:           9385 :         dobj->objType == DO_POST_DATA_BOUNDARY)
                              20235                 :           1694 :         return;
                              20236                 :                : 
                              20237         [ +  + ]:          19706 :     for (i = 0; i < dobj->nDeps; i++)
                              20238                 :                :     {
                              20239                 :          11995 :         DumpId      depid = dobj->dependencies[i];
                              20240                 :                : 
                              20241         [ +  + ]:          11995 :         if (TocIDRequired(AH, depid) != 0)
                              20242                 :                :         {
                              20243                 :                :             /* Object will be dumped, so just reference it as a dependency */
                              20244         [ -  + ]:           6594 :             if (*nDeps >= *allocDeps)
                              20245                 :                :             {
 4821 tgl@sss.pgh.pa.us       20246                 :UBC           0 :                 *allocDeps *= 2;
                              20247                 :              0 :                 *dependencies = (DumpId *) pg_realloc(*dependencies,
 2999                         20248                 :              0 :                                                       *allocDeps * sizeof(DumpId));
                              20249                 :                :             }
 4821 tgl@sss.pgh.pa.us       20250                 :CBC        6594 :             (*dependencies)[*nDeps] = depid;
                              20251                 :           6594 :             (*nDeps)++;
                              20252                 :                :         }
                              20253                 :                :         else
                              20254                 :                :         {
                              20255                 :                :             /*
                              20256                 :                :              * Object will not be dumped, so recursively consider its deps. We
                              20257                 :                :              * rely on the assumption that sortDumpableObjects already broke
                              20258                 :                :              * any dependency loops, else we might recurse infinitely.
                              20259                 :                :              */
                              20260                 :           5401 :             DumpableObject *otherdobj = findObjectByDumpId(depid);
                              20261                 :                : 
                              20262         [ +  - ]:           5401 :             if (otherdobj)
                              20263                 :           5401 :                 findDumpableDependencies(AH, otherdobj,
                              20264                 :                :                                          dependencies, nDeps, allocDeps);
                              20265                 :                :         }
                              20266                 :                :     }
                              20267                 :                : }
                              20268                 :                : 
                              20269                 :                : 
                              20270                 :                : /*
                              20271                 :                :  * getFormattedTypeName - retrieve a nicely-formatted type name for the
                              20272                 :                :  * given type OID.
                              20273                 :                :  *
                              20274                 :                :  * This does not guarantee to schema-qualify the output, so it should not
                              20275                 :                :  * be used to create the target object name for CREATE or ALTER commands.
                              20276                 :                :  *
                              20277                 :                :  * Note that the result is cached and must not be freed by the caller.
                              20278                 :                :  */
                              20279                 :                : static const char *
 4961 rhaas@postgresql.org    20280                 :           2372 : getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
                              20281                 :                : {
                              20282                 :                :     TypeInfo   *typeInfo;
                              20283                 :                :     char       *result;
                              20284                 :                :     PQExpBuffer query;
                              20285                 :                :     PGresult   *res;
                              20286                 :                : 
 7945 tgl@sss.pgh.pa.us       20287         [ -  + ]:           2372 :     if (oid == 0)
                              20288                 :                :     {
 2011 tgl@sss.pgh.pa.us       20289         [ #  # ]:UBC           0 :         if ((opts & zeroAsStar) != 0)
 1459                         20290                 :              0 :             return "*";
 8520                         20291         [ #  # ]:              0 :         else if ((opts & zeroAsNone) != 0)
 1459                         20292                 :              0 :             return "NONE";
                              20293                 :                :     }
                              20294                 :                : 
                              20295                 :                :     /* see if we have the result cached in the type's TypeInfo record */
 1467 tgl@sss.pgh.pa.us       20296                 :CBC        2372 :     typeInfo = findTypeByOid(oid);
                              20297   [ +  -  +  + ]:           2372 :     if (typeInfo && typeInfo->ftypname)
 1459                         20298                 :           1863 :         return typeInfo->ftypname;
                              20299                 :                : 
 8520                         20300                 :            509 :     query = createPQExpBuffer();
 3251                         20301                 :            509 :     appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
                              20302                 :                :                       oid);
                              20303                 :                : 
 4951 rhaas@postgresql.org    20304                 :            509 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              20305                 :                : 
                              20306                 :                :     /* result of format_type is already quoted */
 3251 tgl@sss.pgh.pa.us       20307                 :            509 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              20308                 :                : 
 8520                         20309                 :            509 :     PQclear(res);
                              20310                 :            509 :     destroyPQExpBuffer(query);
                              20311                 :                : 
                              20312                 :                :     /*
                              20313                 :                :      * Cache the result for re-use in later requests, if possible.  If we
                              20314                 :                :      * don't have a TypeInfo for the type, the string will be leaked once the
                              20315                 :                :      * caller is done with it ... but that case really should not happen, so
                              20316                 :                :      * leaking if it does seems acceptable.
                              20317                 :                :      */
 1467                         20318         [ +  - ]:            509 :     if (typeInfo)
 1459                         20319                 :            509 :         typeInfo->ftypname = result;
                              20320                 :                : 
 8520                         20321                 :            509 :     return result;
                              20322                 :                : }
                              20323                 :                : 
                              20324                 :                : /*
                              20325                 :                :  * Return a column list clause for the given relation.
                              20326                 :                :  *
                              20327                 :                :  * Special case: if there are no undropped columns in the relation, return
                              20328                 :                :  * "", not an invalid "()" column list.
                              20329                 :                :  */
                              20330                 :                : static const char *
 4549 andrew@dunslane.net     20331                 :           8738 : fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
                              20332                 :                : {
 8451 bruce@momjian.us        20333                 :           8738 :     int         numatts = ti->numatts;
 8403                         20334                 :           8738 :     char      **attnames = ti->attnames;
                              20335                 :           8738 :     bool       *attisdropped = ti->attisdropped;
 2352 peter@eisentraut.org    20336                 :           8738 :     char       *attgenerated = ti->attgenerated;
                              20337                 :                :     bool        needComma;
                              20338                 :                :     int         i;
                              20339                 :                : 
 4310 heikki.linnakangas@i    20340                 :           8738 :     appendPQExpBufferChar(buffer, '(');
 8436 tgl@sss.pgh.pa.us       20341                 :           8738 :     needComma = false;
 8451 bruce@momjian.us        20342         [ +  + ]:          41562 :     for (i = 0; i < numatts; i++)
                              20343                 :                :     {
 8436 tgl@sss.pgh.pa.us       20344         [ +  + ]:          32824 :         if (attisdropped[i])
                              20345                 :            610 :             continue;
 2352 peter@eisentraut.org    20346         [ +  + ]:          32214 :         if (attgenerated[i])
                              20347                 :           1200 :             continue;
 8436 tgl@sss.pgh.pa.us       20348         [ +  + ]:          31014 :         if (needComma)
 4310 heikki.linnakangas@i    20349                 :          22536 :             appendPQExpBufferStr(buffer, ", ");
                              20350                 :          31014 :         appendPQExpBufferStr(buffer, fmtId(attnames[i]));
 8436 tgl@sss.pgh.pa.us       20351                 :          31014 :         needComma = true;
                              20352                 :                :     }
                              20353                 :                : 
 8304                         20354         [ +  + ]:           8738 :     if (!needComma)
 8170                         20355                 :            260 :         return "";                /* no undropped columns */
                              20356                 :                : 
 4310 heikki.linnakangas@i    20357                 :           8478 :     appendPQExpBufferChar(buffer, ')');
 4549 andrew@dunslane.net     20358                 :           8478 :     return buffer->data;
                              20359                 :                : }
                              20360                 :                : 
                              20361                 :                : /*
                              20362                 :                :  * Check if a reloptions array is nonempty.
                              20363                 :                :  */
                              20364                 :                : static bool
 3535 tgl@sss.pgh.pa.us       20365                 :          14288 : nonemptyReloptions(const char *reloptions)
                              20366                 :                : {
                              20367                 :                :     /* Don't want to print it if it's just "{}" */
                              20368   [ +  -  +  + ]:          14288 :     return (reloptions != NULL && strlen(reloptions) > 2);
                              20369                 :                : }
                              20370                 :                : 
                              20371                 :                : /*
                              20372                 :                :  * Format a reloptions array and append it to the given buffer.
                              20373                 :                :  *
                              20374                 :                :  * "prefix" is prepended to the option names; typically it's "" or "toast.".
                              20375                 :                :  */
                              20376                 :                : static void
 3410 dean.a.rasheed@gmail    20377                 :            220 : appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
                              20378                 :                :                         const char *prefix, Archive *fout)
                              20379                 :                : {
                              20380                 :                :     bool        res;
                              20381                 :                : 
                              20382                 :            220 :     res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
                              20383                 :            220 :                                 fout->std_strings);
                              20384         [ -  + ]:            220 :     if (!res)
 1407 peter@eisentraut.org    20385                 :UBC           0 :         pg_log_warning("could not parse %s array", "reloptions");
 3535 tgl@sss.pgh.pa.us       20386                 :CBC         220 : }
                              20387                 :                : 
                              20388                 :                : /*
                              20389                 :                :  * read_dump_filters - retrieve object identifier patterns from file
                              20390                 :                :  *
                              20391                 :                :  * Parse the specified filter file for include and exclude patterns, and add
                              20392                 :                :  * them to the relevant lists.  If the filename is "-" then filters will be
                              20393                 :                :  * read from STDIN rather than a file.
                              20394                 :                :  */
                              20395                 :                : static void
  647 dgustafsson@postgres    20396                 :             26 : read_dump_filters(const char *filename, DumpOptions *dopt)
                              20397                 :                : {
                              20398                 :                :     FilterStateData fstate;
                              20399                 :                :     char       *objname;
                              20400                 :                :     FilterCommandType comtype;
                              20401                 :                :     FilterObjectType objtype;
                              20402                 :                : 
                              20403                 :             26 :     filter_init(&fstate, filename, exit_nicely);
                              20404                 :                : 
                              20405         [ +  + ]:             84 :     while (filter_read_item(&fstate, &objname, &comtype, &objtype))
                              20406                 :                :     {
                              20407         [ +  + ]:             33 :         if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
                              20408                 :                :         {
                              20409   [ -  -  +  +  :             17 :             switch (objtype)
                                        +  +  +  - ]
                              20410                 :                :             {
  647 dgustafsson@postgres    20411                 :UBC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              20412                 :              0 :                     break;
                              20413                 :              0 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              20414                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              20415                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              20416                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              20417                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              20418                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
  646                         20419                 :              0 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              20420                 :                :                                         "include",
                              20421                 :                :                                         filter_object_type_name(objtype));
  647                         20422                 :              0 :                     exit_nicely(1);
                              20423                 :                :                     break;      /* unreachable */
                              20424                 :                : 
  647 dgustafsson@postgres    20425                 :CBC           1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              20426                 :              1 :                     simple_string_list_append(&extension_include_patterns, objname);
                              20427                 :              1 :                     break;
                              20428                 :              1 :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
                              20429                 :              1 :                     simple_string_list_append(&foreign_servers_include_patterns, objname);
                              20430                 :              1 :                     break;
                              20431                 :              1 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              20432                 :              1 :                     simple_string_list_append(&schema_include_patterns, objname);
                              20433                 :              1 :                     dopt->include_everything = false;
                              20434                 :              1 :                     break;
                              20435                 :             13 :                 case FILTER_OBJECT_TYPE_TABLE:
                              20436                 :             13 :                     simple_string_list_append(&table_include_patterns, objname);
                              20437                 :             13 :                     dopt->include_everything = false;
                              20438                 :             13 :                     break;
                              20439                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              20440                 :              1 :                     simple_string_list_append(&table_include_patterns_and_children,
                              20441                 :                :                                               objname);
                              20442                 :              1 :                     dopt->include_everything = false;
                              20443                 :              1 :                     break;
                              20444                 :                :             }
                              20445                 :                :         }
                              20446         [ +  + ]:             16 :         else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
                              20447                 :                :         {
                              20448   [ -  +  +  +  :              9 :             switch (objtype)
                                        +  +  +  +  
                                                 - ]
                              20449                 :                :             {
  647 dgustafsson@postgres    20450                 :UBC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              20451                 :              0 :                     break;
  647 dgustafsson@postgres    20452                 :CBC           1 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              20453                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              20454                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              20455                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
                              20456                 :                :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
  646                         20457                 :              1 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              20458                 :                :                                         "exclude",
                              20459                 :                :                                         filter_object_type_name(objtype));
  647                         20460                 :              1 :                     exit_nicely(1);
                              20461                 :                :                     break;
                              20462                 :                : 
  535 dean.a.rasheed@gmail    20463                 :              1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              20464                 :              1 :                     simple_string_list_append(&extension_exclude_patterns, objname);
                              20465                 :              1 :                     break;
  647 dgustafsson@postgres    20466                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              20467                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns,
                              20468                 :                :                                               objname);
                              20469                 :              1 :                     break;
                              20470                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              20471                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns_and_children,
                              20472                 :                :                                               objname);
                              20473                 :              1 :                     break;
                              20474                 :              2 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              20475                 :              2 :                     simple_string_list_append(&schema_exclude_patterns, objname);
                              20476                 :              2 :                     break;
                              20477                 :              2 :                 case FILTER_OBJECT_TYPE_TABLE:
                              20478                 :              2 :                     simple_string_list_append(&table_exclude_patterns, objname);
                              20479                 :              2 :                     break;
                              20480                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              20481                 :              1 :                     simple_string_list_append(&table_exclude_patterns_and_children,
                              20482                 :                :                                               objname);
                              20483                 :              1 :                     break;
                              20484                 :                :             }
                              20485                 :                :         }
                              20486                 :                :         else
                              20487                 :                :         {
                              20488         [ -  + ]:              7 :             Assert(comtype == FILTER_COMMAND_TYPE_NONE);
                              20489         [ -  + ]:              7 :             Assert(objtype == FILTER_OBJECT_TYPE_NONE);
                              20490                 :                :         }
                              20491                 :                : 
                              20492         [ +  + ]:             32 :         if (objname)
                              20493                 :             25 :             free(objname);
                              20494                 :                :     }
                              20495                 :                : 
                              20496                 :             22 :     filter_free(&fstate);
                              20497                 :             22 : }
        

Generated by: LCOV version 2.4-beta