LCOV - differential code coverage report
Current view: top level - src/bin/pg_dump - pg_dump.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC DUB DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 89.8 % 7741 6952 48 4 737 17 385 6550 90 127
Current Date: 2024-04-14 14:21:10 Functions: 97.7 % 176 172 4 40 132
Baseline: 16@8cea358b128 Branches: 76.5 % 3550 2715 83 3 1 748 12 3 210 2490
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 88.4 % 164 145 19 144 1
(60,120] days: 95.7 % 117 112 4 1 102 10
(120,180] days: 88.4 % 86 76 7 3 53 23
(180,240] days: 75.0 % 128 96 17 15 86 10
(240..) days: 90.0 % 7246 6523 1 4 718 17 6506
Function coverage date bins:
(60,120] days: 100.0 % 3 3 2 1
(120,180] days: 100.0 % 1 1 1
(240..) days: 97.7 % 172 168 4 37 131
Branch coverage date bins:
[..60] days: 67.7 % 130 88 42 88
(60,120] days: 72.6 % 62 45 15 2 41 4
(120,180] days: 73.0 % 37 27 7 3 22 5
(180,240] days: 63.4 % 112 71 19 22 59 12
(240..) days: 77.4 % 3209 2484 3 1 721 12 3 2469

 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-2024, 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_default_acl_d.h"
                                 51                 :                : #include "catalog/pg_largeobject_d.h"
                                 52                 :                : #include "catalog/pg_largeobject_metadata_d.h"
                                 53                 :                : #include "catalog/pg_proc_d.h"
                                 54                 :                : #include "catalog/pg_subscription.h"
                                 55                 :                : #include "catalog/pg_trigger_d.h"
                                 56                 :                : #include "catalog/pg_type_d.h"
                                 57                 :                : #include "common/connect.h"
                                 58                 :                : #include "common/relpath.h"
                                 59                 :                : #include "compress_io.h"
                                 60                 :                : #include "dumputils.h"
                                 61                 :                : #include "fe_utils/option_utils.h"
                                 62                 :                : #include "fe_utils/string_utils.h"
                                 63                 :                : #include "filter.h"
                                 64                 :                : #include "getopt_long.h"
                                 65                 :                : #include "libpq/libpq-fs.h"
                                 66                 :                : #include "parallel.h"
                                 67                 :                : #include "pg_backup_db.h"
                                 68                 :                : #include "pg_backup_utils.h"
                                 69                 :                : #include "pg_dump.h"
                                 70                 :                : #include "storage/block.h"
                                 71                 :                : 
                                 72                 :                : typedef struct
                                 73                 :                : {
                                 74                 :                :     Oid         roleoid;        /* role's OID */
                                 75                 :                :     const char *rolename;       /* role's name */
                                 76                 :                : } RoleNameItem;
                                 77                 :                : 
                                 78                 :                : typedef struct
                                 79                 :                : {
                                 80                 :                :     const char *descr;          /* comment for an object */
                                 81                 :                :     Oid         classoid;       /* object class (catalog OID) */
                                 82                 :                :     Oid         objoid;         /* object OID */
                                 83                 :                :     int         objsubid;       /* subobject (table column #) */
                                 84                 :                : } CommentItem;
                                 85                 :                : 
                                 86                 :                : typedef struct
                                 87                 :                : {
                                 88                 :                :     const char *provider;       /* label provider of this security label */
                                 89                 :                :     const char *label;          /* security label for an object */
                                 90                 :                :     Oid         classoid;       /* object class (catalog OID) */
                                 91                 :                :     Oid         objoid;         /* object OID */
                                 92                 :                :     int         objsubid;       /* subobject (table column #) */
                                 93                 :                : } SecLabelItem;
                                 94                 :                : 
                                 95                 :                : typedef enum OidOptions
                                 96                 :                : {
                                 97                 :                :     zeroIsError = 1,
                                 98                 :                :     zeroAsStar = 2,
                                 99                 :                :     zeroAsNone = 4,
                                100                 :                : } OidOptions;
                                101                 :                : 
                                102                 :                : /* global decls */
                                103                 :                : static bool dosync = true;      /* Issue fsync() to make dump durable on disk. */
                                104                 :                : 
                                105                 :                : static Oid  g_last_builtin_oid; /* value of the last builtin oid */
                                106                 :                : 
                                107                 :                : /* The specified names/patterns should to match at least one entity */
                                108                 :                : static int  strict_names = 0;
                                109                 :                : 
                                110                 :                : static pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE;
                                111                 :                : 
                                112                 :                : /*
                                113                 :                :  * Object inclusion/exclusion lists
                                114                 :                :  *
                                115                 :                :  * The string lists record the patterns given by command-line switches,
                                116                 :                :  * which we then convert to lists of OIDs of matching objects.
                                117                 :                :  */
                                118                 :                : static SimpleStringList schema_include_patterns = {NULL, NULL};
                                119                 :                : static SimpleOidList schema_include_oids = {NULL, NULL};
                                120                 :                : static SimpleStringList schema_exclude_patterns = {NULL, NULL};
                                121                 :                : static SimpleOidList schema_exclude_oids = {NULL, NULL};
                                122                 :                : 
                                123                 :                : static SimpleStringList table_include_patterns = {NULL, NULL};
                                124                 :                : static SimpleStringList table_include_patterns_and_children = {NULL, NULL};
                                125                 :                : static SimpleOidList table_include_oids = {NULL, NULL};
                                126                 :                : static SimpleStringList table_exclude_patterns = {NULL, NULL};
                                127                 :                : static SimpleStringList table_exclude_patterns_and_children = {NULL, NULL};
                                128                 :                : static SimpleOidList table_exclude_oids = {NULL, NULL};
                                129                 :                : static SimpleStringList tabledata_exclude_patterns = {NULL, NULL};
                                130                 :                : static SimpleStringList tabledata_exclude_patterns_and_children = {NULL, NULL};
                                131                 :                : static SimpleOidList tabledata_exclude_oids = {NULL, NULL};
                                132                 :                : 
                                133                 :                : static SimpleStringList foreign_servers_include_patterns = {NULL, NULL};
                                134                 :                : static SimpleOidList foreign_servers_include_oids = {NULL, NULL};
                                135                 :                : 
                                136                 :                : static SimpleStringList extension_include_patterns = {NULL, NULL};
                                137                 :                : static SimpleOidList extension_include_oids = {NULL, NULL};
                                138                 :                : 
                                139                 :                : static SimpleStringList extension_exclude_patterns = {NULL, NULL};
                                140                 :                : static SimpleOidList extension_exclude_oids = {NULL, NULL};
                                141                 :                : 
                                142                 :                : static const CatalogId nilCatalogId = {0, 0};
                                143                 :                : 
                                144                 :                : /* override for standard extra_float_digits setting */
                                145                 :                : static bool have_extra_float_digits = false;
                                146                 :                : static int  extra_float_digits;
                                147                 :                : 
                                148                 :                : /* sorted table of role names */
                                149                 :                : static RoleNameItem *rolenames = NULL;
                                150                 :                : static int  nrolenames = 0;
                                151                 :                : 
                                152                 :                : /* sorted table of comments */
                                153                 :                : static CommentItem *comments = NULL;
                                154                 :                : static int  ncomments = 0;
                                155                 :                : 
                                156                 :                : /* sorted table of security labels */
                                157                 :                : static SecLabelItem *seclabels = NULL;
                                158                 :                : static int  nseclabels = 0;
                                159                 :                : 
                                160                 :                : /*
                                161                 :                :  * The default number of rows per INSERT when
                                162                 :                :  * --inserts is specified without --rows-per-insert
                                163                 :                :  */
                                164                 :                : #define DUMP_DEFAULT_ROWS_PER_INSERT 1
                                165                 :                : 
                                166                 :                : /*
                                167                 :                :  * Maximum number of large objects to group into a single ArchiveEntry.
                                168                 :                :  * At some point we might want to make this user-controllable, but for now
                                169                 :                :  * a hard-wired setting will suffice.
                                170                 :                :  */
                                171                 :                : #define MAX_BLOBS_PER_ARCHIVE_ENTRY 1000
                                172                 :                : 
                                173                 :                : /*
                                174                 :                :  * Macro for producing quoted, schema-qualified name of a dumpable object.
                                175                 :                :  */
                                176                 :                : #define fmtQualifiedDumpable(obj) \
                                177                 :                :     fmtQualifiedId((obj)->dobj.namespace->dobj.name, \
                                178                 :                :                    (obj)->dobj.name)
                                179                 :                : 
                                180                 :                : static void help(const char *progname);
                                181                 :                : static void setup_connection(Archive *AH,
                                182                 :                :                              const char *dumpencoding, const char *dumpsnapshot,
                                183                 :                :                              char *use_role);
                                184                 :                : static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
                                185                 :                : static void expand_schema_name_patterns(Archive *fout,
                                186                 :                :                                         SimpleStringList *patterns,
                                187                 :                :                                         SimpleOidList *oids,
                                188                 :                :                                         bool strict_names);
                                189                 :                : static void expand_extension_name_patterns(Archive *fout,
                                190                 :                :                                            SimpleStringList *patterns,
                                191                 :                :                                            SimpleOidList *oids,
                                192                 :                :                                            bool strict_names);
                                193                 :                : static void expand_foreign_server_name_patterns(Archive *fout,
                                194                 :                :                                                 SimpleStringList *patterns,
                                195                 :                :                                                 SimpleOidList *oids);
                                196                 :                : static void expand_table_name_patterns(Archive *fout,
                                197                 :                :                                        SimpleStringList *patterns,
                                198                 :                :                                        SimpleOidList *oids,
                                199                 :                :                                        bool strict_names,
                                200                 :                :                                        bool with_child_tables);
                                201                 :                : static void prohibit_crossdb_refs(PGconn *conn, const char *dbname,
                                202                 :                :                                   const char *pattern);
                                203                 :                : 
                                204                 :                : static NamespaceInfo *findNamespace(Oid nsoid);
                                205                 :                : static void dumpTableData(Archive *fout, const TableDataInfo *tdinfo);
                                206                 :                : static void refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo);
                                207                 :                : static const char *getRoleName(const char *roleoid_str);
                                208                 :                : static void collectRoleNames(Archive *fout);
                                209                 :                : static void getAdditionalACLs(Archive *fout);
                                210                 :                : static void dumpCommentExtended(Archive *fout, const char *type,
                                211                 :                :                                 const char *name, const char *namespace,
                                212                 :                :                                 const char *owner, CatalogId catalogId,
                                213                 :                :                                 int subid, DumpId dumpId,
                                214                 :                :                                 const char *initdb_comment);
                                215                 :                : static inline void dumpComment(Archive *fout, const char *type,
                                216                 :                :                                const char *name, const char *namespace,
                                217                 :                :                                const char *owner, CatalogId catalogId,
                                218                 :                :                                int subid, DumpId dumpId);
                                219                 :                : static int  findComments(Oid classoid, Oid objoid, CommentItem **items);
                                220                 :                : static void collectComments(Archive *fout);
                                221                 :                : static void dumpSecLabel(Archive *fout, const char *type, const char *name,
                                222                 :                :                          const char *namespace, const char *owner,
                                223                 :                :                          CatalogId catalogId, int subid, DumpId dumpId);
                                224                 :                : static int  findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items);
                                225                 :                : static void collectSecLabels(Archive *fout);
                                226                 :                : static void dumpDumpableObject(Archive *fout, DumpableObject *dobj);
                                227                 :                : static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo);
                                228                 :                : static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo);
                                229                 :                : static void dumpType(Archive *fout, const TypeInfo *tyinfo);
                                230                 :                : static void dumpBaseType(Archive *fout, const TypeInfo *tyinfo);
                                231                 :                : static void dumpEnumType(Archive *fout, const TypeInfo *tyinfo);
                                232                 :                : static void dumpRangeType(Archive *fout, const TypeInfo *tyinfo);
                                233                 :                : static void dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo);
                                234                 :                : static void dumpDomain(Archive *fout, const TypeInfo *tyinfo);
                                235                 :                : static void dumpCompositeType(Archive *fout, const TypeInfo *tyinfo);
                                236                 :                : static void dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
                                237                 :                :                                          PGresult *res);
                                238                 :                : static void dumpShellType(Archive *fout, const ShellTypeInfo *stinfo);
                                239                 :                : static void dumpProcLang(Archive *fout, const ProcLangInfo *plang);
                                240                 :                : static void dumpFunc(Archive *fout, const FuncInfo *finfo);
                                241                 :                : static void dumpCast(Archive *fout, const CastInfo *cast);
                                242                 :                : static void dumpTransform(Archive *fout, const TransformInfo *transform);
                                243                 :                : static void dumpOpr(Archive *fout, const OprInfo *oprinfo);
                                244                 :                : static void dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo);
                                245                 :                : static void dumpOpclass(Archive *fout, const OpclassInfo *opcinfo);
                                246                 :                : static void dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo);
                                247                 :                : static void dumpCollation(Archive *fout, const CollInfo *collinfo);
                                248                 :                : static void dumpConversion(Archive *fout, const ConvInfo *convinfo);
                                249                 :                : static void dumpRule(Archive *fout, const RuleInfo *rinfo);
                                250                 :                : static void dumpAgg(Archive *fout, const AggInfo *agginfo);
                                251                 :                : static void dumpTrigger(Archive *fout, const TriggerInfo *tginfo);
                                252                 :                : static void dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo);
                                253                 :                : static void dumpTable(Archive *fout, const TableInfo *tbinfo);
                                254                 :                : static void dumpTableSchema(Archive *fout, const TableInfo *tbinfo);
                                255                 :                : static void dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo);
                                256                 :                : static void dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo);
                                257                 :                : static void dumpSequence(Archive *fout, const TableInfo *tbinfo);
                                258                 :                : static void dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo);
                                259                 :                : static void dumpIndex(Archive *fout, const IndxInfo *indxinfo);
                                260                 :                : static void dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo);
                                261                 :                : static void dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo);
                                262                 :                : static void dumpConstraint(Archive *fout, const ConstraintInfo *coninfo);
                                263                 :                : static void dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo);
                                264                 :                : static void dumpTSParser(Archive *fout, const TSParserInfo *prsinfo);
                                265                 :                : static void dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo);
                                266                 :                : static void dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo);
                                267                 :                : static void dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo);
                                268                 :                : static void dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo);
                                269                 :                : static void dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo);
                                270                 :                : static void dumpUserMappings(Archive *fout,
                                271                 :                :                              const char *servername, const char *namespace,
                                272                 :                :                              const char *owner, CatalogId catalogId, DumpId dumpId);
                                273                 :                : static void dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo);
                                274                 :                : 
                                275                 :                : static DumpId dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
                                276                 :                :                       const char *type, const char *name, const char *subname,
                                277                 :                :                       const char *nspname, const char *tag, const char *owner,
                                278                 :                :                       const DumpableAcl *dacl);
                                279                 :                : 
                                280                 :                : static void getDependencies(Archive *fout);
                                281                 :                : static void BuildArchiveDependencies(Archive *fout);
                                282                 :                : static void findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
                                283                 :                :                                      DumpId **dependencies, int *nDeps, int *allocDeps);
                                284                 :                : 
                                285                 :                : static DumpableObject *createBoundaryObjects(void);
                                286                 :                : static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
                                287                 :                :                                     DumpableObject *boundaryObjs);
                                288                 :                : 
                                289                 :                : static void addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx);
                                290                 :                : static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
                                291                 :                : static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind);
                                292                 :                : static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo);
                                293                 :                : static void buildMatViewRefreshDependencies(Archive *fout);
                                294                 :                : static void getTableDataFKConstraints(void);
                                295                 :                : static char *format_function_arguments(const FuncInfo *finfo, const char *funcargs,
                                296                 :                :                                        bool is_agg);
                                297                 :                : static char *format_function_signature(Archive *fout,
                                298                 :                :                                        const FuncInfo *finfo, bool honor_quotes);
                                299                 :                : static char *convertRegProcReference(const char *proc);
                                300                 :                : static char *getFormattedOperatorName(const char *oproid);
                                301                 :                : static char *convertTSFunction(Archive *fout, Oid funcOid);
                                302                 :                : static const char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
                                303                 :                : static void getLOs(Archive *fout);
                                304                 :                : static void dumpLO(Archive *fout, const LoInfo *loinfo);
                                305                 :                : static int  dumpLOs(Archive *fout, const void *arg);
                                306                 :                : static void dumpPolicy(Archive *fout, const PolicyInfo *polinfo);
                                307                 :                : static void dumpPublication(Archive *fout, const PublicationInfo *pubinfo);
                                308                 :                : static void dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo);
                                309                 :                : static void dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo);
                                310                 :                : static void dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo);
                                311                 :                : static void dumpDatabase(Archive *fout);
                                312                 :                : static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                                313                 :                :                                const char *dbname, Oid dboid);
                                314                 :                : static void dumpEncoding(Archive *AH);
                                315                 :                : static void dumpStdStrings(Archive *AH);
                                316                 :                : static void dumpSearchPath(Archive *AH);
                                317                 :                : static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                                318                 :                :                                                      PQExpBuffer upgrade_buffer,
                                319                 :                :                                                      Oid pg_type_oid,
                                320                 :                :                                                      bool force_array_type,
                                321                 :                :                                                      bool include_multirange_type);
                                322                 :                : static void binary_upgrade_set_type_oids_by_rel(Archive *fout,
                                323                 :                :                                                 PQExpBuffer upgrade_buffer,
                                324                 :                :                                                 const TableInfo *tbinfo);
                                325                 :                : static void binary_upgrade_set_pg_class_oids(Archive *fout,
                                326                 :                :                                              PQExpBuffer upgrade_buffer,
                                327                 :                :                                              Oid pg_class_oid, bool is_index);
                                328                 :                : static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                                329                 :                :                                             const DumpableObject *dobj,
                                330                 :                :                                             const char *objtype,
                                331                 :                :                                             const char *objname,
                                332                 :                :                                             const char *objnamespace);
                                333                 :                : static const char *getAttrName(int attrnum, const TableInfo *tblInfo);
                                334                 :                : static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
                                335                 :                : static bool nonemptyReloptions(const char *reloptions);
                                336                 :                : static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
                                337                 :                :                                     const char *prefix, Archive *fout);
                                338                 :                : static char *get_synchronized_snapshot(Archive *fout);
                                339                 :                : static void setupDumpWorker(Archive *AH);
                                340                 :                : static TableInfo *getRootTableInfo(const TableInfo *tbinfo);
                                341                 :                : static bool forcePartitionRootLoad(const TableInfo *tbinfo);
                                342                 :                : static void read_dump_filters(const char *filename, DumpOptions *dopt);
                                343                 :                : 
                                344                 :                : 
                                345                 :                : int
 8010 tgl@sss.pgh.pa.us         346                 :CBC         244 : main(int argc, char **argv)
                                347                 :                : {
                                348                 :                :     int         c;
                                349                 :            244 :     const char *filename = NULL;
                                350                 :            244 :     const char *format = "p";
                                351                 :                :     TableInfo  *tblinfo;
                                352                 :                :     int         numTables;
                                353                 :                :     DumpableObject **dobjs;
                                354                 :                :     int         numObjs;
                                355                 :                :     DumpableObject *boundaryObjs;
                                356                 :                :     int         i;
                                357                 :                :     int         optindex;
                                358                 :                :     RestoreOptions *ropt;
                                359                 :                :     Archive    *fout;           /* the script file */
 1840 peter@eisentraut.org      360                 :            244 :     bool        g_verbose = false;
 3470 alvherre@alvh.no-ip.      361                 :            244 :     const char *dumpencoding = NULL;
 3436 simon@2ndQuadrant.co      362                 :            244 :     const char *dumpsnapshot = NULL;
 3470 alvherre@alvh.no-ip.      363                 :            244 :     char       *use_role = NULL;
 4039 andrew@dunslane.net       364                 :            244 :     int         numWorkers = 1;
 8010 tgl@sss.pgh.pa.us         365                 :            244 :     int         plainText = 0;
 4830 heikki.linnakangas@i      366                 :            244 :     ArchiveFormat archiveFormat = archUnknown;
                                367                 :                :     ArchiveMode archiveMode;
  499 michael@paquier.xyz       368                 :            244 :     pg_compress_specification compression_spec = {0};
                                369                 :            244 :     char       *compression_detail = NULL;
                                370                 :            244 :     char       *compression_algorithm_str = "none";
                                371                 :            244 :     char       *error_detail = NULL;
                                372                 :            244 :     bool        user_compression_defined = false;
  221 nathan@postgresql.or      373                 :GNC         244 :     DataDirSyncMethod sync_method = DATA_DIR_SYNC_METHOD_FSYNC;
                                374                 :                : 
                                375                 :                :     static DumpOptions dopt;
                                376                 :                : 
                                377                 :                :     static struct option long_options[] = {
                                378                 :                :         {"data-only", no_argument, NULL, 'a'},
                                379                 :                :         {"blobs", no_argument, NULL, 'b'},
                                380                 :                :         {"large-objects", no_argument, NULL, 'b'},
                                381                 :                :         {"no-blobs", no_argument, NULL, 'B'},
                                382                 :                :         {"no-large-objects", no_argument, NULL, 'B'},
                                383                 :                :         {"clean", no_argument, NULL, 'c'},
                                384                 :                :         {"create", no_argument, NULL, 'C'},
                                385                 :                :         {"dbname", required_argument, NULL, 'd'},
                                386                 :                :         {"extension", required_argument, NULL, 'e'},
                                387                 :                :         {"file", required_argument, NULL, 'f'},
                                388                 :                :         {"format", required_argument, NULL, 'F'},
                                389                 :                :         {"host", required_argument, NULL, 'h'},
                                390                 :                :         {"jobs", 1, NULL, 'j'},
                                391                 :                :         {"no-reconnect", no_argument, NULL, 'R'},
                                392                 :                :         {"no-owner", no_argument, NULL, 'O'},
                                393                 :                :         {"port", required_argument, NULL, 'p'},
                                394                 :                :         {"schema", required_argument, NULL, 'n'},
                                395                 :                :         {"exclude-schema", required_argument, NULL, 'N'},
                                396                 :                :         {"schema-only", no_argument, NULL, 's'},
                                397                 :                :         {"superuser", required_argument, NULL, 'S'},
                                398                 :                :         {"table", required_argument, NULL, 't'},
                                399                 :                :         {"exclude-table", required_argument, NULL, 'T'},
                                400                 :                :         {"no-password", no_argument, NULL, 'w'},
                                401                 :                :         {"password", no_argument, NULL, 'W'},
                                402                 :                :         {"username", required_argument, NULL, 'U'},
                                403                 :                :         {"verbose", no_argument, NULL, 'v'},
                                404                 :                :         {"no-privileges", no_argument, NULL, 'x'},
                                405                 :                :         {"no-acl", no_argument, NULL, 'x'},
                                406                 :                :         {"compress", required_argument, NULL, 'Z'},
                                407                 :                :         {"encoding", required_argument, NULL, 'E'},
                                408                 :                :         {"help", no_argument, NULL, '?'},
                                409                 :                :         {"version", no_argument, NULL, 'V'},
                                410                 :                : 
                                411                 :                :         /*
                                412                 :                :          * the following options don't have an equivalent short option letter
                                413                 :                :          */
                                414                 :                :         {"attribute-inserts", no_argument, &dopt.column_inserts, 1},
                                415                 :                :         {"binary-upgrade", no_argument, &dopt.binary_upgrade, 1},
                                416                 :                :         {"column-inserts", no_argument, &dopt.column_inserts, 1},
                                417                 :                :         {"disable-dollar-quoting", no_argument, &dopt.disable_dollar_quoting, 1},
                                418                 :                :         {"disable-triggers", no_argument, &dopt.disable_triggers, 1},
                                419                 :                :         {"enable-row-security", no_argument, &dopt.enable_row_security, 1},
                                420                 :                :         {"exclude-table-data", required_argument, NULL, 4},
                                421                 :                :         {"extra-float-digits", required_argument, NULL, 8},
                                422                 :                :         {"if-exists", no_argument, &dopt.if_exists, 1},
                                423                 :                :         {"inserts", no_argument, NULL, 9},
                                424                 :                :         {"lock-wait-timeout", required_argument, NULL, 2},
                                425                 :                :         {"no-table-access-method", no_argument, &dopt.outputNoTableAm, 1},
                                426                 :                :         {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1},
                                427                 :                :         {"quote-all-identifiers", no_argument, &quote_all_identifiers, 1},
                                428                 :                :         {"load-via-partition-root", no_argument, &dopt.load_via_partition_root, 1},
                                429                 :                :         {"role", required_argument, NULL, 3},
                                430                 :                :         {"section", required_argument, NULL, 5},
                                431                 :                :         {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
                                432                 :                :         {"snapshot", required_argument, NULL, 6},
                                433                 :                :         {"strict-names", no_argument, &strict_names, 1},
                                434                 :                :         {"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
                                435                 :                :         {"no-comments", no_argument, &dopt.no_comments, 1},
                                436                 :                :         {"no-publications", no_argument, &dopt.no_publications, 1},
                                437                 :                :         {"no-security-labels", no_argument, &dopt.no_security_labels, 1},
                                438                 :                :         {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1},
                                439                 :                :         {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1},
                                440                 :                :         {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1},
                                441                 :                :         {"no-sync", no_argument, NULL, 7},
                                442                 :                :         {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1},
                                443                 :                :         {"rows-per-insert", required_argument, NULL, 10},
                                444                 :                :         {"include-foreign-data", required_argument, NULL, 11},
                                445                 :                :         {"table-and-children", required_argument, NULL, 12},
                                446                 :                :         {"exclude-table-and-children", required_argument, NULL, 13},
                                447                 :                :         {"exclude-table-data-and-children", required_argument, NULL, 14},
                                448                 :                :         {"sync-method", required_argument, NULL, 15},
                                449                 :                :         {"filter", required_argument, NULL, 16},
                                450                 :                :         {"exclude-extension", required_argument, NULL, 17},
                                451                 :                : 
                                452                 :                :         {NULL, 0, NULL, 0}
                                453                 :                :     };
                                454                 :                : 
 1840 peter@eisentraut.org      455                 :CBC         244 :     pg_logging_init(argv[0]);
                                456                 :            244 :     pg_logging_set_level(PG_LOG_WARNING);
 5603 peter_e@gmx.net           457                 :            244 :     set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
                                458                 :                : 
                                459                 :                :     /*
                                460                 :                :      * Initialize what we need for parallel execution, especially for thread
                                461                 :                :      * support on Windows.
                                462                 :                :      */
 4039 andrew@dunslane.net       463                 :            244 :     init_parallel_dump_utils();
                                464                 :                : 
 7681 bruce@momjian.us          465                 :            244 :     progname = get_progname(argv[0]);
                                466                 :                : 
 8010 tgl@sss.pgh.pa.us         467         [ +  - ]:            244 :     if (argc > 1)
                                468                 :                :     {
                                469   [ +  +  -  + ]:            244 :         if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                                470                 :                :         {
                                471                 :              1 :             help(progname);
 4441 rhaas@postgresql.org      472                 :              1 :             exit_nicely(0);
                                473                 :                :         }
 8010 tgl@sss.pgh.pa.us         474   [ +  +  +  + ]:            243 :         if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                                475                 :                :         {
                                476                 :             47 :             puts("pg_dump (PostgreSQL) " PG_VERSION);
 4441 rhaas@postgresql.org      477                 :             47 :             exit_nicely(0);
                                478                 :                :         }
                                479                 :                :     }
                                480                 :                : 
 3381 tgl@sss.pgh.pa.us         481                 :            196 :     InitDumpOptions(&dopt);
                                482                 :                : 
 1110 michael@paquier.xyz       483                 :            846 :     while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:",
 7769 peter_e@gmx.net           484         [ +  + ]:            846 :                             long_options, &optindex)) != -1)
                                485                 :                :     {
 8010 tgl@sss.pgh.pa.us         486   [ +  +  +  +  :            658 :         switch (c)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     -  +  +  +  +  
                                     +  +  +  -  +  
                                     +  +  +  +  +  
                                     +  +  -  +  +  
                                                 + ]
                                487                 :                :         {
                                488                 :              8 :             case 'a':           /* Dump data only */
 3381                           489                 :              8 :                 dopt.dataOnly = true;
 8010                           490                 :              8 :                 break;
                                491                 :                : 
  496 peter@eisentraut.org      492                 :              1 :             case 'b':           /* Dump LOs */
                                493                 :              1 :                 dopt.outputLOs = true;
 8010 tgl@sss.pgh.pa.us         494                 :              1 :                 break;
                                495                 :                : 
  496 peter@eisentraut.org      496                 :              2 :             case 'B':           /* Don't dump LOs */
                                497                 :              2 :                 dopt.dontOutputLOs = true;
 2693 sfrost@snowman.net        498                 :              2 :                 break;
                                499                 :                : 
 6756 bruce@momjian.us          500                 :              6 :             case 'c':           /* clean (i.e., drop) schema prior to create */
 3381 tgl@sss.pgh.pa.us         501                 :              6 :                 dopt.outputClean = 1;
 8010                           502                 :              6 :                 break;
                                503                 :                : 
                                504                 :             29 :             case 'C':           /* Create DB */
 3381                           505                 :             29 :                 dopt.outputCreateDB = 1;
 8010                           506                 :             29 :                 break;
                                507                 :                : 
 4066 heikki.linnakangas@i      508                 :              5 :             case 'd':           /* database name */
 1298 tgl@sss.pgh.pa.us         509                 :              5 :                 dopt.cparams.dbname = pg_strdup(optarg);
 4066 heikki.linnakangas@i      510                 :              5 :                 break;
                                511                 :                : 
 1110 michael@paquier.xyz       512                 :              4 :             case 'e':           /* include extension(s) */
                                513                 :              4 :                 simple_string_list_append(&extension_include_patterns, optarg);
                                514                 :              4 :                 dopt.include_everything = false;
                                515                 :              4 :                 break;
                                516                 :                : 
 6853 bruce@momjian.us          517                 :              2 :             case 'E':           /* Dump encoding */
 4202                           518                 :              2 :                 dumpencoding = pg_strdup(optarg);
 6853                           519                 :              2 :                 break;
                                520                 :                : 
 8010 tgl@sss.pgh.pa.us         521                 :            154 :             case 'f':
 4202 bruce@momjian.us          522                 :            154 :                 filename = pg_strdup(optarg);
 8010 tgl@sss.pgh.pa.us         523                 :            154 :                 break;
                                524                 :                : 
                                525                 :             88 :             case 'F':
 4202 bruce@momjian.us          526                 :             88 :                 format = pg_strdup(optarg);
 8010 tgl@sss.pgh.pa.us         527                 :             88 :                 break;
                                528                 :                : 
                                529                 :             12 :             case 'h':           /* server host */
 1298                           530                 :             12 :                 dopt.cparams.pghost = pg_strdup(optarg);
 8010                           531                 :             12 :                 break;
                                532                 :                : 
 4039 andrew@dunslane.net       533                 :             12 :             case 'j':           /* number of dump jobs */
  995 michael@paquier.xyz       534         [ +  + ]:             12 :                 if (!option_parse_int(optarg, "-j/--jobs", 1,
                                535                 :                :                                       PG_MAX_JOBS,
                                536                 :                :                                       &numWorkers))
                                537                 :              1 :                     exit_nicely(1);
 4039 andrew@dunslane.net       538                 :             11 :                 break;
                                539                 :                : 
 6397 tgl@sss.pgh.pa.us         540                 :             15 :             case 'n':           /* include schema(s) */
                                541                 :             15 :                 simple_string_list_append(&schema_include_patterns, optarg);
 3381                           542                 :             15 :                 dopt.include_everything = false;
 6397                           543                 :             15 :                 break;
                                544                 :                : 
                                545                 :              1 :             case 'N':           /* exclude schema(s) */
                                546                 :              1 :                 simple_string_list_append(&schema_exclude_patterns, optarg);
 7731 bruce@momjian.us          547                 :              1 :                 break;
                                548                 :                : 
 8010 tgl@sss.pgh.pa.us         549                 :              2 :             case 'O':           /* Don't reconnect to match owner */
 3381                           550                 :              2 :                 dopt.outputNoOwner = 1;
 8010                           551                 :              2 :                 break;
                                552                 :                : 
                                553                 :             48 :             case 'p':           /* server port */
 1298                           554                 :             48 :                 dopt.cparams.pgport = pg_strdup(optarg);
 8010                           555                 :             48 :                 break;
                                556                 :                : 
 7509                           557                 :              2 :             case 'R':
                                558                 :                :                 /* no-op, still accepted for backwards compatibility */
 8010                           559                 :              2 :                 break;
                                560                 :                : 
                                561                 :             18 :             case 's':           /* dump schema only */
 3381                           562                 :             18 :                 dopt.schemaOnly = true;
 8010                           563                 :             18 :                 break;
                                564                 :                : 
 6756 bruce@momjian.us          565                 :              1 :             case 'S':           /* Username for superuser in plain text output */
 3381 tgl@sss.pgh.pa.us         566                 :              1 :                 dopt.outputSuperuser = pg_strdup(optarg);
 8010                           567                 :              1 :                 break;
                                568                 :                : 
 6397                           569                 :              8 :             case 't':           /* include table(s) */
                                570                 :              8 :                 simple_string_list_append(&table_include_patterns, optarg);
 3381                           571                 :              8 :                 dopt.include_everything = false;
 6397                           572                 :              8 :                 break;
                                573                 :                : 
                                574                 :              4 :             case 'T':           /* exclude table(s) */
                                575                 :              4 :                 simple_string_list_append(&table_exclude_patterns, optarg);
                                576                 :              4 :                 break;
                                577                 :                : 
 8010                           578                 :             14 :             case 'U':
 1298                           579                 :             14 :                 dopt.cparams.username = pg_strdup(optarg);
 8010                           580                 :             14 :                 break;
                                581                 :                : 
                                582                 :              6 :             case 'v':           /* verbose */
                                583                 :              6 :                 g_verbose = true;
 1305                           584                 :              6 :                 pg_logging_increase_verbosity();
 8010                           585                 :              6 :                 break;
                                586                 :                : 
 5526 peter_e@gmx.net           587                 :              1 :             case 'w':
 1298 tgl@sss.pgh.pa.us         588                 :              1 :                 dopt.cparams.promptPassword = TRI_NO;
 5526 peter_e@gmx.net           589                 :              1 :                 break;
                                590                 :                : 
 8010 tgl@sss.pgh.pa.us         591                 :UBC           0 :             case 'W':
 1298                           592                 :              0 :                 dopt.cparams.promptPassword = TRI_YES;
 8010                           593                 :              0 :                 break;
                                594                 :                : 
 8010 tgl@sss.pgh.pa.us         595                 :CBC           2 :             case 'x':           /* skip ACL dump */
 3381                           596                 :              2 :                 dopt.aclsSkip = true;
 8010                           597                 :              2 :                 break;
                                598                 :                : 
  499 michael@paquier.xyz       599                 :             15 :             case 'Z':           /* Compression */
                                600                 :             15 :                 parse_compress_options(optarg, &compression_algorithm_str,
                                601                 :                :                                        &compression_detail);
                                602                 :             15 :                 user_compression_defined = true;
 8010 tgl@sss.pgh.pa.us         603                 :             15 :                 break;
                                604                 :                : 
                                605                 :             49 :             case 0:
                                606                 :                :                 /* This covers the long options. */
                                607                 :             49 :                 break;
                                608                 :                : 
 5578                           609                 :              2 :             case 2:             /* lock-wait-timeout */
 3381                           610                 :              2 :                 dopt.lockWaitTimeout = pg_strdup(optarg);
 5747                           611                 :              2 :                 break;
                                612                 :                : 
 5578                           613                 :              3 :             case 3:             /* SET ROLE */
 4202 bruce@momjian.us          614                 :              3 :                 use_role = pg_strdup(optarg);
 5578 tgl@sss.pgh.pa.us         615                 :              3 :                 break;
                                616                 :                : 
 4326 bruce@momjian.us          617                 :              1 :             case 4:             /* exclude table(s) data */
 4505 andrew@dunslane.net       618                 :              1 :                 simple_string_list_append(&tabledata_exclude_patterns, optarg);
                                619                 :              1 :                 break;
                                620                 :                : 
 4503                           621                 :              6 :             case 5:             /* section */
 3381 tgl@sss.pgh.pa.us         622                 :              6 :                 set_dump_section(optarg, &dopt.dumpSections);
 4503 andrew@dunslane.net       623                 :              6 :                 break;
                                624                 :                : 
 3436 simon@2ndQuadrant.co      625                 :UBC           0 :             case 6:             /* snapshot */
                                626                 :              0 :                 dumpsnapshot = pg_strdup(optarg);
                                627                 :              0 :                 break;
                                628                 :                : 
 2580 andrew@dunslane.net       629                 :CBC          97 :             case 7:             /* no-sync */
                                630                 :             97 :                 dosync = false;
                                631                 :             97 :                 break;
                                632                 :                : 
 1882                           633                 :              1 :             case 8:
                                634                 :              1 :                 have_extra_float_digits = true;
  995 michael@paquier.xyz       635         [ +  - ]:              1 :                 if (!option_parse_int(optarg, "--extra-float-digits", -15, 3,
                                636                 :                :                                       &extra_float_digits))
 1882 andrew@dunslane.net       637                 :              1 :                     exit_nicely(1);
 1882 andrew@dunslane.net       638                 :UBC           0 :                 break;
                                639                 :                : 
 1865 alvherre@alvh.no-ip.      640                 :CBC           2 :             case 9:             /* inserts */
                                641                 :                : 
                                642                 :                :                 /*
                                643                 :                :                  * dump_inserts also stores --rows-per-insert, careful not to
                                644                 :                :                  * overwrite that.
                                645                 :                :                  */
                                646         [ +  - ]:              2 :                 if (dopt.dump_inserts == 0)
                                647                 :              2 :                     dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT;
                                648                 :              2 :                 break;
                                649                 :                : 
                                650                 :              2 :             case 10:            /* rows per insert */
  995 michael@paquier.xyz       651         [ +  + ]:              2 :                 if (!option_parse_int(optarg, "--rows-per-insert", 1, INT_MAX,
                                652                 :                :                                       &dopt.dump_inserts))
 1865 alvherre@alvh.no-ip.      653                 :              1 :                     exit_nicely(1);
                                654                 :              1 :                 break;
                                655                 :                : 
 1481                           656                 :              4 :             case 11:            /* include foreign data */
                                657                 :              4 :                 simple_string_list_append(&foreign_servers_include_patterns,
                                658                 :                :                                           optarg);
                                659                 :              4 :                 break;
                                660                 :                : 
  397 tgl@sss.pgh.pa.us         661                 :              1 :             case 12:            /* include table(s) and their children */
                                662                 :              1 :                 simple_string_list_append(&table_include_patterns_and_children,
                                663                 :                :                                           optarg);
                                664                 :              1 :                 dopt.include_everything = false;
                                665                 :              1 :                 break;
                                666                 :                : 
                                667                 :              1 :             case 13:            /* exclude table(s) and their children */
                                668                 :              1 :                 simple_string_list_append(&table_exclude_patterns_and_children,
                                669                 :                :                                           optarg);
                                670                 :              1 :                 break;
                                671                 :                : 
                                672                 :              1 :             case 14:            /* exclude data of table(s) and children */
                                673                 :              1 :                 simple_string_list_append(&tabledata_exclude_patterns_and_children,
                                674                 :                :                                           optarg);
                                675                 :              1 :                 break;
                                676                 :                : 
  221 nathan@postgresql.or      677                 :UNC           0 :             case 15:
                                678         [ #  # ]:              0 :                 if (!parse_sync_method(optarg, &sync_method))
                                679                 :              0 :                     exit_nicely(1);
                                680                 :              0 :                 break;
                                681                 :                : 
  137 dgustafsson@postgres      682                 :GNC          26 :             case 16:            /* read object filters from file */
                                683                 :             26 :                 read_dump_filters(optarg, &dopt);
                                684                 :             22 :                 break;
                                685                 :                : 
   25 dean.a.rasheed@gmail      686                 :              1 :             case 17:            /* exclude extension(s) */
                                687                 :              1 :                 simple_string_list_append(&extension_exclude_patterns,
                                688                 :                :                                           optarg);
                                689                 :              1 :                 break;
                                690                 :                : 
 8010 tgl@sss.pgh.pa.us         691                 :CBC           1 :             default:
                                692                 :                :                 /* getopt_long already emitted a complaint */
  737                           693                 :              1 :                 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 4441 rhaas@postgresql.org      694                 :              1 :                 exit_nicely(1);
                                695                 :                :         }
                                696                 :                :     }
                                697                 :                : 
                                698                 :                :     /*
                                699                 :                :      * Non-option argument specifies database name as long as it wasn't
                                700                 :                :      * already specified with -d / --dbname
                                701                 :                :      */
 1298 tgl@sss.pgh.pa.us         702   [ +  +  +  - ]:            188 :     if (optind < argc && dopt.cparams.dbname == NULL)
                                703                 :            156 :         dopt.cparams.dbname = argv[optind++];
                                704                 :                : 
                                705                 :                :     /* Complain if any arguments remain */
 4993                           706         [ +  + ]:            188 :     if (optind < argc)
                                707                 :                :     {
 1840 peter@eisentraut.org      708                 :              1 :         pg_log_error("too many command-line arguments (first is \"%s\")",
                                709                 :                :                      argv[optind]);
  737 tgl@sss.pgh.pa.us         710                 :              1 :         pg_log_error_hint("Try \"%s --help\" for more information.", progname);
 4441 rhaas@postgresql.org      711                 :              1 :         exit_nicely(1);
                                712                 :                :     }
                                713                 :                : 
                                714                 :                :     /* --column-inserts implies --inserts */
 1865 alvherre@alvh.no-ip.      715   [ +  +  +  - ]:            187 :     if (dopt.column_inserts && dopt.dump_inserts == 0)
                                716                 :              1 :         dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT;
                                717                 :                : 
                                718                 :                :     /*
                                719                 :                :      * Binary upgrade mode implies dumping sequence data even in schema-only
                                720                 :                :      * mode.  This is not exposed as a separate option, but kept separate
                                721                 :                :      * internally for clarity.
                                722                 :                :      */
 2791 peter_e@gmx.net           723         [ +  + ]:            187 :     if (dopt.binary_upgrade)
                                724                 :             14 :         dopt.sequence_data = 1;
                                725                 :                : 
 3381 tgl@sss.pgh.pa.us         726   [ +  +  +  + ]:            187 :     if (dopt.dataOnly && dopt.schemaOnly)
  737                           727                 :              1 :         pg_fatal("options -s/--schema-only and -a/--data-only cannot be used together");
                                728                 :                : 
 1481 alvherre@alvh.no-ip.      729   [ +  +  +  + ]:            186 :     if (dopt.schemaOnly && foreign_servers_include_patterns.head != NULL)
  737 tgl@sss.pgh.pa.us         730                 :              1 :         pg_fatal("options -s/--schema-only and --include-foreign-data cannot be used together");
                                731                 :                : 
 1481 alvherre@alvh.no-ip.      732   [ +  +  +  + ]:            185 :     if (numWorkers > 1 && foreign_servers_include_patterns.head != NULL)
  737 tgl@sss.pgh.pa.us         733                 :              1 :         pg_fatal("option --include-foreign-data is not supported with parallel backup");
                                734                 :                : 
 3381                           735   [ +  +  +  + ]:            184 :     if (dopt.dataOnly && dopt.outputClean)
  737                           736                 :              1 :         pg_fatal("options -c/--clean and -a/--data-only cannot be used together");
                                737                 :                : 
 3381                           738   [ +  +  +  + ]:            183 :     if (dopt.if_exists && !dopt.outputClean)
  737                           739                 :              1 :         pg_fatal("option --if-exists requires option -c/--clean");
                                740                 :                : 
                                741                 :                :     /*
                                742                 :                :      * --inserts are already implied above if --column-inserts or
                                743                 :                :      * --rows-per-insert were specified.
                                744                 :                :      */
 1865 alvherre@alvh.no-ip.      745   [ +  +  +  - ]:            182 :     if (dopt.do_nothing && dopt.dump_inserts == 0)
  737 tgl@sss.pgh.pa.us         746                 :              1 :         pg_fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts");
                                747                 :                : 
                                748                 :                :     /* Identify archive format to emit */
 4830 heikki.linnakangas@i      749                 :            181 :     archiveFormat = parseArchiveFormat(format, &archiveMode);
                                750                 :                : 
                                751                 :                :     /* archiveFormat specific setup */
                                752         [ +  + ]:            180 :     if (archiveFormat == archNull)
 6233 bruce@momjian.us          753                 :            146 :         plainText = 1;
                                754                 :                : 
                                755                 :                :     /*
                                756                 :                :      * Custom and directory formats are compressed by default with gzip when
                                757                 :                :      * available, not the others.  If gzip is not available, no compression is
                                758                 :                :      * done by default.
                                759                 :                :      */
  353 michael@paquier.xyz       760   [ +  +  +  + ]:            180 :     if ((archiveFormat == archCustom || archiveFormat == archDirectory) &&
                                761         [ +  + ]:             31 :         !user_compression_defined)
                                762                 :                :     {
                                763                 :                : #ifdef HAVE_LIBZ
                                764                 :             24 :         compression_algorithm_str = "gzip";
                                765                 :                : #else
                                766                 :                :         compression_algorithm_str = "none";
                                767                 :                : #endif
                                768                 :                :     }
                                769                 :                : 
                                770                 :                :     /*
                                771                 :                :      * Compression options
                                772                 :                :      */
  499                           773         [ +  + ]:            180 :     if (!parse_compress_algorithm(compression_algorithm_str,
                                774                 :                :                                   &compression_algorithm))
                                775                 :              1 :         pg_fatal("unrecognized compression algorithm: \"%s\"",
                                776                 :                :                  compression_algorithm_str);
                                777                 :                : 
                                778                 :            179 :     parse_compress_specification(compression_algorithm, compression_detail,
                                779                 :                :                                  &compression_spec);
                                780                 :            179 :     error_detail = validate_compress_specification(&compression_spec);
                                781         [ +  + ]:            179 :     if (error_detail != NULL)
                                782                 :              3 :         pg_fatal("invalid compression specification: %s",
                                783                 :                :                  error_detail);
                                784                 :                : 
  375 tomas.vondra@postgre      785                 :            176 :     error_detail = supports_compression(compression_spec);
                                786         [ -  + ]:            176 :     if (error_detail != NULL)
  375 tomas.vondra@postgre      787                 :UBC           0 :         pg_fatal("%s", error_detail);
                                788                 :                : 
                                789                 :                :     /*
                                790                 :                :      * Disable support for zstd workers for now - these are based on
                                791                 :                :      * threading, and it's unclear how it interacts with parallel dumps on
                                792                 :                :      * platforms where that relies on threads too (e.g. Windows).
                                793                 :                :      */
  375 tomas.vondra@postgre      794         [ -  + ]:CBC         176 :     if (compression_spec.options & PG_COMPRESSION_OPTION_WORKERS)
  375 tomas.vondra@postgre      795                 :UBC           0 :         pg_log_warning("compression option \"%s\" is not currently supported by pg_dump",
                                796                 :                :                        "workers");
                                797                 :                : 
                                798                 :                :     /*
                                799                 :                :      * If emitting an archive format, we always want to emit a DATABASE item,
                                800                 :                :      * in case --create is specified at pg_restore time.
                                801                 :                :      */
 2271 tgl@sss.pgh.pa.us         802         [ +  + ]:CBC         176 :     if (!plainText)
                                803                 :             34 :         dopt.outputCreateDB = 1;
                                804                 :                : 
                                805                 :                :     /* Parallel backup only in the directory archive format so far */
 4039 andrew@dunslane.net       806   [ +  +  +  + ]:            176 :     if (archiveFormat != archDirectory && numWorkers > 1)
  737 tgl@sss.pgh.pa.us         807                 :              1 :         pg_fatal("parallel backup only supported by the directory format");
                                808                 :                : 
                                809                 :                :     /* Open the output file */
  499 michael@paquier.xyz       810                 :            175 :     fout = CreateArchive(filename, archiveFormat, compression_spec,
                                811                 :                :                          dosync, archiveMode, setupDumpWorker, sync_method);
                                812                 :                : 
                                813                 :                :     /* Make dump options accessible right away */
 3014 tgl@sss.pgh.pa.us         814                 :            174 :     SetArchiveOptions(fout, &dopt, NULL);
                                815                 :                : 
                                816                 :                :     /* Register the cleanup hook */
 4408 alvherre@alvh.no-ip.      817                 :            174 :     on_exit_close_archive(fout);
                                818                 :                : 
                                819                 :                :     /* Let the archiver know how noisy to be */
 4451 rhaas@postgresql.org      820                 :            174 :     fout->verbose = g_verbose;
                                821                 :                : 
                                822                 :                : 
                                823                 :                :     /*
                                824                 :                :      * We allow the server to be back to 9.2, and up to any minor release of
                                825                 :                :      * our own major version.  (See also version check in pg_dumpall.c.)
                                826                 :                :      */
  852 tgl@sss.pgh.pa.us         827                 :            174 :     fout->minRemoteVersion = 90200;
 4037 heikki.linnakangas@i      828                 :            174 :     fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
                                829                 :                : 
 4039 andrew@dunslane.net       830                 :            174 :     fout->numWorkers = numWorkers;
                                831                 :                : 
                                832                 :                :     /*
                                833                 :                :      * Open the database using the Archiver, so it knows about it. Errors mean
                                834                 :                :      * death.
                                835                 :                :      */
 1298 tgl@sss.pgh.pa.us         836                 :            174 :     ConnectDatabase(fout, &dopt.cparams, false);
 3014                           837                 :            172 :     setup_connection(fout, dumpencoding, dumpsnapshot, use_role);
                                838                 :                : 
                                839                 :                :     /*
                                840                 :                :      * On hot standbys, never try to dump unlogged table data, since it will
                                841                 :                :      * just throw an error.
                                842                 :                :      */
 2880 magnus@hagander.net       843         [ +  + ]:            172 :     if (fout->isStandby)
                                844                 :              3 :         dopt.no_unlogged_table_data = true;
                                845                 :                : 
                                846                 :                :     /*
                                847                 :                :      * Find the last built-in OID, if needed (prior to 8.1)
                                848                 :                :      *
                                849                 :                :      * With 8.1 and above, we can just use FirstNormalObjectId - 1.
                                850                 :                :      */
  852 tgl@sss.pgh.pa.us         851                 :            172 :     g_last_builtin_oid = FirstNormalObjectId - 1;
                                852                 :                : 
 1840 peter@eisentraut.org      853                 :            172 :     pg_log_info("last built-in OID is %u", g_last_builtin_oid);
                                854                 :                : 
                                855                 :                :     /* Expand schema selection patterns into OID lists */
 6397 tgl@sss.pgh.pa.us         856         [ +  + ]:            172 :     if (schema_include_patterns.head != NULL)
                                857                 :                :     {
 4451 rhaas@postgresql.org      858                 :             16 :         expand_schema_name_patterns(fout, &schema_include_patterns,
                                859                 :                :                                     &schema_include_oids,
                                860                 :                :                                     strict_names);
 6397 tgl@sss.pgh.pa.us         861         [ +  + ]:             10 :         if (schema_include_oids.head == NULL)
  737                           862                 :              1 :             pg_fatal("no matching schemas were found");
                                863                 :                :     }
 4451 rhaas@postgresql.org      864                 :            165 :     expand_schema_name_patterns(fout, &schema_exclude_patterns,
                                865                 :                :                                 &schema_exclude_oids,
                                866                 :                :                                 false);
                                867                 :                :     /* non-matching exclusion patterns aren't an error */
                                868                 :                : 
                                869                 :                :     /* Expand table selection patterns into OID lists */
  397 tgl@sss.pgh.pa.us         870                 :            165 :     expand_table_name_patterns(fout, &table_include_patterns,
                                871                 :                :                                &table_include_oids,
                                872                 :                :                                strict_names, false);
                                873                 :            160 :     expand_table_name_patterns(fout, &table_include_patterns_and_children,
                                874                 :                :                                &table_include_oids,
                                875                 :                :                                strict_names, true);
                                876         [ +  + ]:            160 :     if ((table_include_patterns.head != NULL ||
                                877         [ +  + ]:            149 :          table_include_patterns_and_children.head != NULL) &&
                                878         [ +  + ]:             13 :         table_include_oids.head == NULL)
                                879                 :              2 :         pg_fatal("no matching tables were found");
                                880                 :                : 
 4450 rhaas@postgresql.org      881                 :            158 :     expand_table_name_patterns(fout, &table_exclude_patterns,
                                882                 :                :                                &table_exclude_oids,
                                883                 :                :                                false, false);
  397 tgl@sss.pgh.pa.us         884                 :            158 :     expand_table_name_patterns(fout, &table_exclude_patterns_and_children,
                                885                 :                :                                &table_exclude_oids,
                                886                 :                :                                false, true);
                                887                 :                : 
 4450 rhaas@postgresql.org      888                 :            158 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns,
                                889                 :                :                                &tabledata_exclude_oids,
                                890                 :                :                                false, false);
  397 tgl@sss.pgh.pa.us         891                 :            158 :     expand_table_name_patterns(fout, &tabledata_exclude_patterns_and_children,
                                892                 :                :                                &tabledata_exclude_oids,
                                893                 :                :                                false, true);
                                894                 :                : 
 1481 alvherre@alvh.no-ip.      895                 :            158 :     expand_foreign_server_name_patterns(fout, &foreign_servers_include_patterns,
                                896                 :                :                                         &foreign_servers_include_oids);
                                897                 :                : 
                                898                 :                :     /* non-matching exclusion patterns aren't an error */
                                899                 :                : 
                                900                 :                :     /* Expand extension selection patterns into OID lists */
 1110 michael@paquier.xyz       901         [ +  + ]:            157 :     if (extension_include_patterns.head != NULL)
                                902                 :                :     {
                                903                 :              5 :         expand_extension_name_patterns(fout, &extension_include_patterns,
                                904                 :                :                                        &extension_include_oids,
                                905                 :                :                                        strict_names);
                                906         [ +  + ]:              5 :         if (extension_include_oids.head == NULL)
  737 tgl@sss.pgh.pa.us         907                 :GBC           1 :             pg_fatal("no matching extensions were found");
                                908                 :                :     }
   25 dean.a.rasheed@gmail      909                 :GNC         156 :     expand_extension_name_patterns(fout, &extension_exclude_patterns,
                                910                 :                :                                    &extension_exclude_oids,
                                911                 :                :                                    false);
                                912                 :                :     /* non-matching exclusion patterns aren't an error */
                                913                 :                : 
                                914                 :                :     /*
                                915                 :                :      * Dumping LOs is the default for dumps where an inclusion switch is not
                                916                 :                :      * used (an "include everything" dump).  -B can be used to exclude LOs
                                917                 :                :      * from those dumps.  -b can be used to include LOs even when an inclusion
                                918                 :                :      * switch is used.
                                919                 :                :      *
                                920                 :                :      * -s means "schema only" and LOs are data, not schema, so we never
                                921                 :                :      * include LOs when -s is used.
                                922                 :                :      */
  496 peter@eisentraut.org      923   [ +  +  +  +  :CBC         156 :     if (dopt.include_everything && !dopt.schemaOnly && !dopt.dontOutputLOs)
                                              +  + ]
                                924                 :            117 :         dopt.outputLOs = true;
                                925                 :                : 
                                926                 :                :     /*
                                927                 :                :      * Collect role names so we can map object owner OIDs to names.
                                928                 :                :      */
  835 tgl@sss.pgh.pa.us         929                 :            156 :     collectRoleNames(fout);
                                930                 :                : 
                                931                 :                :     /*
                                932                 :                :      * Now scan the database and create DumpableObject structs for all the
                                933                 :                :      * objects we intend to dump.
                                934                 :                :      */
 3014                           935                 :            156 :     tblinfo = getSchemaData(fout, &numTables);
                                936                 :                : 
 3381                           937         [ +  + ]:            155 :     if (!dopt.schemaOnly)
                                938                 :                :     {
 1972 andres@anarazel.de        939                 :            139 :         getTableData(&dopt, tblinfo, numTables, 0);
 4060 kgrittn@postgresql.o      940                 :            139 :         buildMatViewRefreshDependencies(fout);
 3381 tgl@sss.pgh.pa.us         941         [ +  + ]:            139 :         if (dopt.dataOnly)
 5697                           942                 :              6 :             getTableDataFKConstraints();
                                943                 :                :     }
                                944                 :                : 
 2791 peter_e@gmx.net           945   [ +  +  +  + ]:            155 :     if (dopt.schemaOnly && dopt.sequence_data)
 1972 andres@anarazel.de        946                 :             14 :         getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE);
                                947                 :                : 
                                948                 :                :     /*
                                949                 :                :      * In binary-upgrade mode, we do not have to worry about the actual LO
                                950                 :                :      * data or the associated metadata that resides in the pg_largeobject and
                                951                 :                :      * pg_largeobject_metadata tables, respectively.
                                952                 :                :      *
                                953                 :                :      * However, we do need to collect LO information as there may be comments
                                954                 :                :      * or other information on LOs that we do need to dump out.
                                955                 :                :      */
  496 peter@eisentraut.org      956   [ +  +  +  + ]:            155 :     if (dopt.outputLOs || dopt.binary_upgrade)
                                957                 :            131 :         getLOs(fout);
                                958                 :                : 
                                959                 :                :     /*
                                960                 :                :      * Collect dependency data to assist in ordering the objects.
                                961                 :                :      */
 4451 rhaas@postgresql.org      962                 :            155 :     getDependencies(fout);
                                963                 :                : 
                                964                 :                :     /*
                                965                 :                :      * Collect ACLs, comments, and security labels, if wanted.
                                966                 :                :      */
  860 tgl@sss.pgh.pa.us         967         [ +  + ]:            155 :     if (!dopt.aclsSkip)
                                968                 :            153 :         getAdditionalACLs(fout);
                                969         [ +  - ]:            155 :     if (!dopt.no_comments)
                                970                 :            155 :         collectComments(fout);
                                971         [ +  - ]:            155 :     if (!dopt.no_security_labels)
                                972                 :            155 :         collectSecLabels(fout);
                                973                 :                : 
                                974                 :                :     /* Lastly, create dummy objects to represent the section boundaries */
 4311                           975                 :            155 :     boundaryObjs = createBoundaryObjects();
                                976                 :                : 
                                977                 :                :     /* Get pointers to all the known DumpableObjects */
                                978                 :            155 :     getDumpableObjects(&dobjs, &numObjs);
                                979                 :                : 
                                980                 :                :     /*
                                981                 :                :      * Add dummy dependencies to enforce the dump section ordering.
                                982                 :                :      */
                                983                 :            155 :     addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
                                984                 :                : 
                                985                 :                :     /*
                                986                 :                :      * Sort the objects into a safe dump order (no forward references).
                                987                 :                :      *
                                988                 :                :      * We rely on dependency information to help us determine a safe order, so
                                989                 :                :      * the initial sort is mostly for cosmetic purposes: we sort by name to
                                990                 :                :      * ensure that logically identical schemas will dump identically.
                                991                 :                :      */
 2741                           992                 :            155 :     sortDumpableObjectsByTypeName(dobjs, numObjs);
                                993                 :                : 
 4311                           994                 :            155 :     sortDumpableObjects(dobjs, numObjs,
                                995                 :            155 :                         boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
                                996                 :                : 
                                997                 :                :     /*
                                998                 :                :      * Create archive TOC entries for all the objects to be dumped, in a safe
                                999                 :                :      * order.
                               1000                 :                :      */
                               1001                 :                : 
                               1002                 :                :     /*
                               1003                 :                :      * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH.
                               1004                 :                :      */
 4451 rhaas@postgresql.org     1005                 :            155 :     dumpEncoding(fout);
                               1006                 :            155 :     dumpStdStrings(fout);
 2239 tgl@sss.pgh.pa.us        1007                 :            155 :     dumpSearchPath(fout);
                               1008                 :                : 
                               1009                 :                :     /* The database items are always next, unless we don't want them at all */
 2271                          1010         [ +  + ]:            155 :     if (dopt.outputCreateDB)
 3014                          1011                 :             62 :         dumpDatabase(fout);
                               1012                 :                : 
                               1013                 :                :     /* Now the rearrangeable objects. */
 7435                          1014         [ +  + ]:         664403 :     for (i = 0; i < numObjs; i++)
 3014                          1015                 :         664248 :         dumpDumpableObject(fout, dobjs[i]);
                               1016                 :                : 
                               1017                 :                :     /*
                               1018                 :                :      * Set up options info to ensure we dump what we want.
                               1019                 :                :      */
 4338                          1020                 :            155 :     ropt = NewRestoreOptions();
                               1021                 :            155 :     ropt->filename = filename;
                               1022                 :                : 
                               1023                 :                :     /* if you change this list, see dumpOptionsFromRestoreOptions */
 1298                          1024         [ +  + ]:            155 :     ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL;
                               1025         [ +  + ]:            155 :     ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL;
                               1026         [ +  + ]:            155 :     ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL;
                               1027         [ +  + ]:            155 :     ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL;
                               1028                 :            155 :     ropt->cparams.promptPassword = dopt.cparams.promptPassword;
 3381                          1029                 :            155 :     ropt->dropSchema = dopt.outputClean;
                               1030                 :            155 :     ropt->dataOnly = dopt.dataOnly;
                               1031                 :            155 :     ropt->schemaOnly = dopt.schemaOnly;
                               1032                 :            155 :     ropt->if_exists = dopt.if_exists;
                               1033                 :            155 :     ropt->column_inserts = dopt.column_inserts;
                               1034                 :            155 :     ropt->dumpSections = dopt.dumpSections;
                               1035                 :            155 :     ropt->aclsSkip = dopt.aclsSkip;
                               1036                 :            155 :     ropt->superuser = dopt.outputSuperuser;
                               1037                 :            155 :     ropt->createDB = dopt.outputCreateDB;
                               1038                 :            155 :     ropt->noOwner = dopt.outputNoOwner;
  818 michael@paquier.xyz      1039                 :            155 :     ropt->noTableAm = dopt.outputNoTableAm;
 3381 tgl@sss.pgh.pa.us        1040                 :            155 :     ropt->noTablespace = dopt.outputNoTablespaces;
                               1041                 :            155 :     ropt->disable_triggers = dopt.disable_triggers;
                               1042                 :            155 :     ropt->use_setsessauth = dopt.use_setsessauth;
                               1043                 :            155 :     ropt->disable_dollar_quoting = dopt.disable_dollar_quoting;
                               1044                 :            155 :     ropt->dump_inserts = dopt.dump_inserts;
 2271                          1045                 :            155 :     ropt->no_comments = dopt.no_comments;
 2529 peter_e@gmx.net          1046                 :            155 :     ropt->no_publications = dopt.no_publications;
 3381 tgl@sss.pgh.pa.us        1047                 :            155 :     ropt->no_security_labels = dopt.no_security_labels;
 2532 peter_e@gmx.net          1048                 :            155 :     ropt->no_subscriptions = dopt.no_subscriptions;
 3381 tgl@sss.pgh.pa.us        1049                 :            155 :     ropt->lockWaitTimeout = dopt.lockWaitTimeout;
                               1050                 :            155 :     ropt->include_everything = dopt.include_everything;
                               1051                 :            155 :     ropt->enable_row_security = dopt.enable_row_security;
 2791 peter_e@gmx.net          1052                 :            155 :     ropt->sequence_data = dopt.sequence_data;
 2596 sfrost@snowman.net       1053                 :            155 :     ropt->binary_upgrade = dopt.binary_upgrade;
                               1054                 :                : 
  499 michael@paquier.xyz      1055                 :            155 :     ropt->compression_spec = compression_spec;
                               1056                 :                : 
 4326 bruce@momjian.us         1057                 :            155 :     ropt->suppressDumpWarnings = true;   /* We've already shown them */
                               1058                 :                : 
 3014 tgl@sss.pgh.pa.us        1059                 :            155 :     SetArchiveOptions(fout, &dopt, ropt);
                               1060                 :                : 
                               1061                 :                :     /* Mark which entries should be output */
                               1062                 :            155 :     ProcessArchiveRestoreOptions(fout);
                               1063                 :                : 
                               1064                 :                :     /*
                               1065                 :                :      * The archive's TOC entries are now marked as to which ones will actually
                               1066                 :                :      * be output, so we can set up their dependency lists properly. This isn't
                               1067                 :                :      * necessary for plain-text output, though.
                               1068                 :                :      */
 4311                          1069         [ +  + ]:            155 :     if (!plainText)
                               1070                 :             33 :         BuildArchiveDependencies(fout);
                               1071                 :                : 
                               1072                 :                :     /*
                               1073                 :                :      * And finally we can do the actual output.
                               1074                 :                :      *
                               1075                 :                :      * Note: for non-plain-text output formats, the output file is written
                               1076                 :                :      * inside CloseArchive().  This is, um, bizarre; but not worth changing
                               1077                 :                :      * right now.
                               1078                 :                :      */
 4338                          1079         [ +  + ]:            155 :     if (plainText)
                               1080                 :            122 :         RestoreArchive(fout);
                               1081                 :                : 
 3014                          1082                 :            154 :     CloseArchive(fout);
                               1083                 :                : 
 4441 rhaas@postgresql.org     1084                 :            154 :     exit_nicely(0);
                               1085                 :                : }
                               1086                 :                : 
                               1087                 :                : 
                               1088                 :                : static void
 8010 tgl@sss.pgh.pa.us        1089                 :              1 : help(const char *progname)
                               1090                 :                : {
 7900 peter_e@gmx.net          1091                 :              1 :     printf(_("%s dumps a database as a text file or to other formats.\n\n"), progname);
                               1092                 :              1 :     printf(_("Usage:\n"));
 7849                          1093                 :              1 :     printf(_("  %s [OPTION]... [DBNAME]\n"), progname);
                               1094                 :                : 
                               1095                 :              1 :     printf(_("\nGeneral options:\n"));
 4349                          1096                 :              1 :     printf(_("  -f, --file=FILENAME          output file or directory name\n"));
                               1097                 :              1 :     printf(_("  -F, --format=c|d|t|p         output file format (custom, directory, tar,\n"
                               1098                 :                :              "                               plain text (default))\n"));
 4039 andrew@dunslane.net      1099                 :              1 :     printf(_("  -j, --jobs=NUM               use this many parallel jobs to dump\n"));
 4349 peter_e@gmx.net          1100                 :              1 :     printf(_("  -v, --verbose                verbose mode\n"));
 4318                          1101                 :              1 :     printf(_("  -V, --version                output version information, then exit\n"));
  331 peter@eisentraut.org     1102                 :              1 :     printf(_("  -Z, --compress=METHOD[:DETAIL]\n"
                               1103                 :                :              "                               compress as specified\n"));
 4349 peter_e@gmx.net          1104                 :              1 :     printf(_("  --lock-wait-timeout=TIMEOUT  fail after waiting TIMEOUT for a table lock\n"));
 2580 andrew@dunslane.net      1105                 :              1 :     printf(_("  --no-sync                    do not wait for changes to be written safely to disk\n"));
  221 nathan@postgresql.or     1106                 :GNC           1 :     printf(_("  --sync-method=METHOD         set method for syncing files to disk\n"));
 4318 peter_e@gmx.net          1107                 :CBC           1 :     printf(_("  -?, --help                   show this help, then exit\n"));
                               1108                 :                : 
 7849                          1109                 :              1 :     printf(_("\nOptions controlling the output content:\n"));
 4349                          1110                 :              1 :     printf(_("  -a, --data-only              dump only the data, not the schema\n"));
  331 peter@eisentraut.org     1111                 :              1 :     printf(_("  -b, --large-objects          include large objects in dump\n"));
                               1112                 :              1 :     printf(_("  --blobs                      (same as --large-objects, deprecated)\n"));
                               1113                 :              1 :     printf(_("  -B, --no-large-objects       exclude large objects in dump\n"));
                               1114                 :              1 :     printf(_("  --no-blobs                   (same as --no-large-objects, deprecated)\n"));
 4349 peter_e@gmx.net          1115                 :              1 :     printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
                               1116                 :              1 :     printf(_("  -C, --create                 include commands to create database in dump\n"));
 1110 michael@paquier.xyz      1117                 :              1 :     printf(_("  -e, --extension=PATTERN      dump the specified extension(s) only\n"));
   25 dean.a.rasheed@gmail     1118                 :GNC           1 :     printf(_("  --exclude-extension=PATTERN  do NOT dump the specified extension(s)\n"));
 4349 peter_e@gmx.net          1119                 :CBC           1 :     printf(_("  -E, --encoding=ENCODING      dump the data in encoding ENCODING\n"));
 1685 peter@eisentraut.org     1120                 :              1 :     printf(_("  -n, --schema=PATTERN         dump the specified schema(s) only\n"));
                               1121                 :              1 :     printf(_("  -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n"));
 4349 peter_e@gmx.net          1122                 :              1 :     printf(_("  -O, --no-owner               skip restoration of object ownership in\n"
                               1123                 :                :              "                               plain-text format\n"));
                               1124                 :              1 :     printf(_("  -s, --schema-only            dump only the schema, no data\n"));
                               1125                 :              1 :     printf(_("  -S, --superuser=NAME         superuser user name to use in plain-text format\n"));
  397 tgl@sss.pgh.pa.us        1126                 :              1 :     printf(_("  -t, --table=PATTERN          dump only the specified table(s)\n"));
 1685 peter@eisentraut.org     1127                 :              1 :     printf(_("  -T, --exclude-table=PATTERN  do NOT dump the specified table(s)\n"));
 4349 peter_e@gmx.net          1128                 :              1 :     printf(_("  -x, --no-privileges          do not dump privileges (grant/revoke)\n"));
                               1129                 :              1 :     printf(_("  --binary-upgrade             for use by upgrade utilities only\n"));
                               1130                 :              1 :     printf(_("  --column-inserts             dump data as INSERT commands with column names\n"));
                               1131                 :              1 :     printf(_("  --disable-dollar-quoting     disable dollar quoting, use SQL standard quoting\n"));
                               1132                 :              1 :     printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
 3133                          1133                 :              1 :     printf(_("  --enable-row-security        enable row security (dump only content user has\n"
                               1134                 :                :              "                               access to)\n"));
  397 tgl@sss.pgh.pa.us        1135                 :              1 :     printf(_("  --exclude-table-and-children=PATTERN\n"
                               1136                 :                :              "                               do NOT dump the specified table(s), including\n"
                               1137                 :                :              "                               child and partition tables\n"));
 1685 peter@eisentraut.org     1138                 :              1 :     printf(_("  --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n"));
  397 tgl@sss.pgh.pa.us        1139                 :              1 :     printf(_("  --exclude-table-data-and-children=PATTERN\n"
                               1140                 :                :              "                               do NOT dump data for the specified table(s),\n"
                               1141                 :                :              "                               including child and partition tables\n"));
 1882 andrew@dunslane.net      1142                 :              1 :     printf(_("  --extra-float-digits=NUM     override default setting for extra_float_digits\n"));
  137 dgustafsson@postgres     1143                 :GNC           1 :     printf(_("  --filter=FILENAME            include or exclude objects and data from dump\n"
                               1144                 :                :              "                               based on expressions in FILENAME\n"));
 3695 alvherre@alvh.no-ip.     1145                 :CBC           1 :     printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
 1481                          1146                 :              1 :     printf(_("  --include-foreign-data=PATTERN\n"
                               1147                 :                :              "                               include data of foreign tables on foreign\n"
                               1148                 :                :              "                               servers matching PATTERN\n"));
 4349 peter_e@gmx.net          1149                 :              1 :     printf(_("  --inserts                    dump data as INSERT commands, rather than COPY\n"));
 2141                          1150                 :              1 :     printf(_("  --load-via-partition-root    load partitions via the root table\n"));
 2271 tgl@sss.pgh.pa.us        1151                 :              1 :     printf(_("  --no-comments                do not dump comments\n"));
 2529 peter_e@gmx.net          1152                 :              1 :     printf(_("  --no-publications            do not dump publications\n"));
 4349                          1153                 :              1 :     printf(_("  --no-security-labels         do not dump security label assignments\n"));
 2532                          1154                 :              1 :     printf(_("  --no-subscriptions           do not dump subscriptions\n"));
  818 michael@paquier.xyz      1155                 :              1 :     printf(_("  --no-table-access-method     do not dump table access methods\n"));
 4349 peter_e@gmx.net          1156                 :              1 :     printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
 1066 peter@eisentraut.org     1157                 :              1 :     printf(_("  --no-toast-compression       do not dump TOAST compression methods\n"));
 4349 peter_e@gmx.net          1158                 :              1 :     printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
 2102 tmunro@postgresql.or     1159                 :              1 :     printf(_("  --on-conflict-do-nothing     add ON CONFLICT DO NOTHING to INSERT commands\n"));
 4349 peter_e@gmx.net          1160                 :              1 :     printf(_("  --quote-all-identifiers      quote all identifiers, even if not key words\n"));
 1865 alvherre@alvh.no-ip.     1161                 :              1 :     printf(_("  --rows-per-insert=NROWS      number of rows per INSERT; implies --inserts\n"));
 4349 peter_e@gmx.net          1162                 :              1 :     printf(_("  --section=SECTION            dump named section (pre-data, data, or post-data)\n"));
                               1163                 :              1 :     printf(_("  --serializable-deferrable    wait until the dump can run without anomalies\n"));
 3122                          1164                 :              1 :     printf(_("  --snapshot=SNAPSHOT          use given snapshot for the dump\n"));
 3135 teodor@sigaev.ru         1165                 :              1 :     printf(_("  --strict-names               require table and/or schema include patterns to\n"
                               1166                 :                :              "                               match at least one entity each\n"));
  331 peter@eisentraut.org     1167                 :              1 :     printf(_("  --table-and-children=PATTERN dump only the specified table(s), including\n"
                               1168                 :                :              "                               child and partition tables\n"));
 6399 peter_e@gmx.net          1169                 :              1 :     printf(_("  --use-set-session-authorization\n"
                               1170                 :                :              "                               use SET SESSION AUTHORIZATION commands instead of\n"
                               1171                 :                :              "                               ALTER OWNER commands to set ownership\n"));
                               1172                 :                : 
 7849                          1173                 :              1 :     printf(_("\nConnection options:\n"));
 4066 heikki.linnakangas@i     1174                 :              1 :     printf(_("  -d, --dbname=DBNAME      database to dump\n"));
 7613 bruce@momjian.us         1175                 :              1 :     printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
 7849 peter_e@gmx.net          1176                 :              1 :     printf(_("  -p, --port=PORT          database server port number\n"));
                               1177                 :              1 :     printf(_("  -U, --username=NAME      connect as specified database user\n"));
 5507                          1178                 :              1 :     printf(_("  -w, --no-password        never prompt for password\n"));
 7849                          1179                 :              1 :     printf(_("  -W, --password           force password prompt (should happen automatically)\n"));
 4708                          1180                 :              1 :     printf(_("  --role=ROLENAME          do SET ROLE before dump\n"));
                               1181                 :                : 
 7571                          1182                 :              1 :     printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n"
                               1183                 :                :              "variable value is used.\n\n"));
 1507 peter@eisentraut.org     1184                 :              1 :     printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
                               1185                 :              1 :     printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 8010 tgl@sss.pgh.pa.us        1186                 :              1 : }
                               1187                 :                : 
                               1188                 :                : static void
 3014                          1189                 :            190 : setup_connection(Archive *AH, const char *dumpencoding,
                               1190                 :                :                  const char *dumpsnapshot, char *use_role)
                               1191                 :                : {
                               1192                 :            190 :     DumpOptions *dopt = AH->dopt;
 4441 rhaas@postgresql.org     1193                 :            190 :     PGconn     *conn = GetConnection(AH);
                               1194                 :                :     const char *std_strings;
                               1195                 :                : 
 2239 noah@leadboat.com        1196                 :            190 :     PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL));
                               1197                 :                : 
                               1198                 :                :     /*
                               1199                 :                :      * Set the client encoding if requested.
                               1200                 :                :      */
 4461 rhaas@postgresql.org     1201         [ +  + ]:            190 :     if (dumpencoding)
                               1202                 :                :     {
 4441                          1203         [ -  + ]:             20 :         if (PQsetClientEncoding(conn, dumpencoding) < 0)
  737 tgl@sss.pgh.pa.us        1204                 :UBC           0 :             pg_fatal("invalid client encoding \"%s\" specified",
                               1205                 :                :                      dumpencoding);
                               1206                 :                :     }
                               1207                 :                : 
                               1208                 :                :     /*
                               1209                 :                :      * Get the active encoding and the standard_conforming_strings setting, so
                               1210                 :                :      * we know how to escape strings.
                               1211                 :                :      */
 4441 rhaas@postgresql.org     1212                 :CBC         190 :     AH->encoding = PQclientEncoding(conn);
                               1213                 :                : 
                               1214                 :            190 :     std_strings = PQparameterStatus(conn, "standard_conforming_strings");
 4461                          1215   [ +  -  +  - ]:            190 :     AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
                               1216                 :                : 
                               1217                 :                :     /*
                               1218                 :                :      * Set the role if requested.  In a parallel dump worker, we'll be passed
                               1219                 :                :      * use_role == NULL, but AH->use_role is already set (if user specified it
                               1220                 :                :      * originally) and we should use that.
                               1221                 :                :      */
 4039 andrew@dunslane.net      1222   [ +  +  +  + ]:            190 :     if (!use_role && AH->use_role)
                               1223                 :              2 :         use_role = AH->use_role;
                               1224                 :                : 
                               1225                 :                :     /* Set the role if requested */
  852 tgl@sss.pgh.pa.us        1226         [ +  + ]:            190 :     if (use_role)
                               1227                 :                :     {
 4461 rhaas@postgresql.org     1228                 :              5 :         PQExpBuffer query = createPQExpBuffer();
                               1229                 :                : 
                               1230                 :              5 :         appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
 4450                          1231                 :              5 :         ExecuteSqlStatement(AH, query->data);
 4461                          1232                 :              5 :         destroyPQExpBuffer(query);
                               1233                 :                : 
                               1234                 :                :         /* save it for possible later use by parallel workers */
 4039 andrew@dunslane.net      1235         [ +  + ]:              5 :         if (!AH->use_role)
 2874 tgl@sss.pgh.pa.us        1236                 :              3 :             AH->use_role = pg_strdup(use_role);
                               1237                 :                :     }
                               1238                 :                : 
                               1239                 :                :     /* Set the datestyle to ISO to ensure the dump's portability */
 4450 rhaas@postgresql.org     1240                 :            190 :     ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
                               1241                 :                : 
                               1242                 :                :     /* Likewise, avoid using sql_standard intervalstyle */
  852 tgl@sss.pgh.pa.us        1243                 :            190 :     ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
                               1244                 :                : 
                               1245                 :                :     /*
                               1246                 :                :      * Use an explicitly specified extra_float_digits if it has been provided.
                               1247                 :                :      * Otherwise, set extra_float_digits so that we can dump float data
                               1248                 :                :      * exactly (given correctly implemented float I/O code, anyway).
                               1249                 :                :      */
 1882 andrew@dunslane.net      1250         [ -  + ]:            190 :     if (have_extra_float_digits)
                               1251                 :                :     {
 1882 andrew@dunslane.net      1252                 :UBC           0 :         PQExpBuffer q = createPQExpBuffer();
                               1253                 :                : 
                               1254                 :              0 :         appendPQExpBuffer(q, "SET extra_float_digits TO %d",
                               1255                 :                :                           extra_float_digits);
                               1256                 :              0 :         ExecuteSqlStatement(AH, q->data);
                               1257                 :              0 :         destroyPQExpBuffer(q);
                               1258                 :                :     }
                               1259                 :                :     else
  852 tgl@sss.pgh.pa.us        1260                 :CBC         190 :         ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
                               1261                 :                : 
                               1262                 :                :     /*
                               1263                 :                :      * Disable synchronized scanning, to prevent unpredictable changes in row
                               1264                 :                :      * ordering across a dump and reload.
                               1265                 :                :      */
                               1266                 :            190 :     ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
                               1267                 :                : 
                               1268                 :                :     /*
                               1269                 :                :      * Disable timeouts if supported.
                               1270                 :                :      */
 2741                          1271                 :            190 :     ExecuteSqlStatement(AH, "SET statement_timeout = 0");
 4047                          1272         [ +  - ]:            190 :     if (AH->remoteVersion >= 90300)
                               1273                 :            190 :         ExecuteSqlStatement(AH, "SET lock_timeout = 0");
 2860                          1274         [ +  - ]:            190 :     if (AH->remoteVersion >= 90600)
                               1275                 :            190 :         ExecuteSqlStatement(AH, "SET idle_in_transaction_session_timeout = 0");
   59 akorotkov@postgresql     1276         [ +  - ]:GNC         190 :     if (AH->remoteVersion >= 170000)
                               1277                 :            190 :         ExecuteSqlStatement(AH, "SET transaction_timeout = 0");
                               1278                 :                : 
                               1279                 :                :     /*
                               1280                 :                :      * Quote all identifiers, if requested.
                               1281                 :                :      */
  852 tgl@sss.pgh.pa.us        1282         [ +  + ]:CBC         190 :     if (quote_all_identifiers)
 4450 rhaas@postgresql.org     1283                 :             12 :         ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
                               1284                 :                : 
                               1285                 :                :     /*
                               1286                 :                :      * Adjust row-security mode, if supported.
                               1287                 :                :      */
 3343 tgl@sss.pgh.pa.us        1288         [ +  - ]:            190 :     if (AH->remoteVersion >= 90500)
                               1289                 :                :     {
                               1290         [ -  + ]:            190 :         if (dopt->enable_row_security)
 3343 tgl@sss.pgh.pa.us        1291                 :UBC           0 :             ExecuteSqlStatement(AH, "SET row_security = on");
                               1292                 :                :         else
 3343 tgl@sss.pgh.pa.us        1293                 :CBC         190 :             ExecuteSqlStatement(AH, "SET row_security = off");
                               1294                 :                :     }
                               1295                 :                : 
                               1296                 :                :     /*
                               1297                 :                :      * Initialize prepared-query state to "nothing prepared".  We do this here
                               1298                 :                :      * so that a parallel dump worker will have its own state.
                               1299                 :                :      */
  860                          1300                 :            190 :     AH->is_prepared = (bool *) pg_malloc0(NUM_PREP_QUERIES * sizeof(bool));
                               1301                 :                : 
                               1302                 :                :     /*
                               1303                 :                :      * Start transaction-snapshot mode transaction to dump consistent data.
                               1304                 :                :      */
 4039 andrew@dunslane.net      1305                 :            190 :     ExecuteSqlStatement(AH, "BEGIN");
                               1306                 :                : 
                               1307                 :                :     /*
                               1308                 :                :      * To support the combination of serializable_deferrable with the jobs
                               1309                 :                :      * option we use REPEATABLE READ for the worker connections that are
                               1310                 :                :      * passed a snapshot.  As long as the snapshot is acquired in a
                               1311                 :                :      * SERIALIZABLE, READ ONLY, DEFERRABLE transaction, its use within a
                               1312                 :                :      * REPEATABLE READ transaction provides the appropriate integrity
                               1313                 :                :      * guarantees.  This is a kluge, but safe for back-patching.
                               1314                 :                :      */
  852 tgl@sss.pgh.pa.us        1315   [ -  +  -  - ]:            190 :     if (dopt->serializable_deferrable && AH->sync_snapshot_id == NULL)
  852 tgl@sss.pgh.pa.us        1316                 :UBC           0 :         ExecuteSqlStatement(AH,
                               1317                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1318                 :                :                             "SERIALIZABLE, READ ONLY, DEFERRABLE");
                               1319                 :                :     else
 4039 andrew@dunslane.net      1320                 :CBC         190 :         ExecuteSqlStatement(AH,
                               1321                 :                :                             "SET TRANSACTION ISOLATION LEVEL "
                               1322                 :                :                             "REPEATABLE READ, READ ONLY");
                               1323                 :                : 
                               1324                 :                :     /*
                               1325                 :                :      * If user specified a snapshot to use, select that.  In a parallel dump
                               1326                 :                :      * worker, we'll be passed dumpsnapshot == NULL, but AH->sync_snapshot_id
                               1327                 :                :      * is already set (if the server can handle it) and we should use that.
                               1328                 :                :      */
 3436 simon@2ndQuadrant.co     1329         [ -  + ]:            190 :     if (dumpsnapshot)
 2874 tgl@sss.pgh.pa.us        1330                 :UBC           0 :         AH->sync_snapshot_id = pg_strdup(dumpsnapshot);
                               1331                 :                : 
 3436 simon@2ndQuadrant.co     1332         [ +  + ]:CBC         190 :     if (AH->sync_snapshot_id)
                               1333                 :                :     {
                               1334                 :             18 :         PQExpBuffer query = createPQExpBuffer();
                               1335                 :                : 
 1746 drowley@postgresql.o     1336                 :             18 :         appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
 3436 simon@2ndQuadrant.co     1337                 :             18 :         appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
                               1338                 :             18 :         ExecuteSqlStatement(AH, query->data);
                               1339                 :             18 :         destroyPQExpBuffer(query);
                               1340                 :                :     }
  851 tgl@sss.pgh.pa.us        1341         [ +  + ]:            172 :     else if (AH->numWorkers > 1)
                               1342                 :                :     {
 2433 peter_e@gmx.net          1343   [ -  +  -  - ]:              9 :         if (AH->isStandby && AH->remoteVersion < 100000)
  737 tgl@sss.pgh.pa.us        1344                 :UBC           0 :             pg_fatal("parallel dumps from standby servers are not supported by this server version");
 3436 simon@2ndQuadrant.co     1345                 :CBC           9 :         AH->sync_snapshot_id = get_synchronized_snapshot(AH);
                               1346                 :                :     }
 4039 andrew@dunslane.net      1347                 :            190 : }
                               1348                 :                : 
                               1349                 :                : /* Set up connection for a parallel worker process */
                               1350                 :                : static void
 2874 tgl@sss.pgh.pa.us        1351                 :             18 : setupDumpWorker(Archive *AH)
                               1352                 :                : {
                               1353                 :                :     /*
                               1354                 :                :      * We want to re-select all the same values the leader connection is
                               1355                 :                :      * using.  We'll have inherited directly-usable values in
                               1356                 :                :      * AH->sync_snapshot_id and AH->use_role, but we need to translate the
                               1357                 :                :      * inherited encoding value back to a string to pass to setup_connection.
                               1358                 :                :      */
                               1359                 :             18 :     setup_connection(AH,
                               1360                 :                :                      pg_encoding_to_char(AH->encoding),
                               1361                 :                :                      NULL,
                               1362                 :                :                      NULL);
 4039 andrew@dunslane.net      1363                 :             18 : }
                               1364                 :                : 
                               1365                 :                : static char *
                               1366                 :              9 : get_synchronized_snapshot(Archive *fout)
                               1367                 :                : {
 2874 tgl@sss.pgh.pa.us        1368                 :              9 :     char       *query = "SELECT pg_catalog.pg_export_snapshot()";
                               1369                 :                :     char       *result;
                               1370                 :                :     PGresult   *res;
                               1371                 :                : 
 4039 andrew@dunslane.net      1372                 :              9 :     res = ExecuteSqlQueryForSingleRow(fout, query);
 2874 tgl@sss.pgh.pa.us        1373                 :              9 :     result = pg_strdup(PQgetvalue(res, 0, 0));
 4039 andrew@dunslane.net      1374                 :              9 :     PQclear(res);
                               1375                 :                : 
                               1376                 :              9 :     return result;
                               1377                 :                : }
                               1378                 :                : 
                               1379                 :                : static ArchiveFormat
 4830 heikki.linnakangas@i     1380                 :            181 : parseArchiveFormat(const char *format, ArchiveMode *mode)
                               1381                 :                : {
                               1382                 :                :     ArchiveFormat archiveFormat;
                               1383                 :                : 
                               1384                 :            181 :     *mode = archModeWrite;
                               1385                 :                : 
                               1386   [ +  +  -  + ]:            181 :     if (pg_strcasecmp(format, "a") == 0 || pg_strcasecmp(format, "append") == 0)
                               1387                 :                :     {
                               1388                 :                :         /* This is used by pg_dumpall, and is not documented */
                               1389                 :             43 :         archiveFormat = archNull;
                               1390                 :             43 :         *mode = archModeAppend;
                               1391                 :                :     }
                               1392         [ +  + ]:            138 :     else if (pg_strcasecmp(format, "c") == 0)
                               1393                 :              4 :         archiveFormat = archCustom;
                               1394         [ +  + ]:            134 :     else if (pg_strcasecmp(format, "custom") == 0)
                               1395                 :             16 :         archiveFormat = archCustom;
                               1396         [ +  + ]:            118 :     else if (pg_strcasecmp(format, "d") == 0)
                               1397                 :              7 :         archiveFormat = archDirectory;
                               1398         [ +  + ]:            111 :     else if (pg_strcasecmp(format, "directory") == 0)
                               1399                 :              4 :         archiveFormat = archDirectory;
                               1400         [ +  + ]:            107 :     else if (pg_strcasecmp(format, "p") == 0)
                               1401                 :             99 :         archiveFormat = archNull;
                               1402         [ +  + ]:              8 :     else if (pg_strcasecmp(format, "plain") == 0)
                               1403                 :              4 :         archiveFormat = archNull;
                               1404         [ +  + ]:              4 :     else if (pg_strcasecmp(format, "t") == 0)
                               1405                 :              2 :         archiveFormat = archTar;
                               1406         [ +  + ]:              2 :     else if (pg_strcasecmp(format, "tar") == 0)
                               1407                 :              1 :         archiveFormat = archTar;
                               1408                 :                :     else
  737 tgl@sss.pgh.pa.us        1409                 :              1 :         pg_fatal("invalid output format \"%s\" specified", format);
 4830 heikki.linnakangas@i     1410                 :            180 :     return archiveFormat;
                               1411                 :                : }
                               1412                 :                : 
                               1413                 :                : /*
                               1414                 :                :  * Find the OIDs of all schemas matching the given list of patterns,
                               1415                 :                :  * and append them to the given OID list.
                               1416                 :                :  */
                               1417                 :                : static void
 4451 rhaas@postgresql.org     1418                 :            181 : expand_schema_name_patterns(Archive *fout,
                               1419                 :                :                             SimpleStringList *patterns,
                               1420                 :                :                             SimpleOidList *oids,
                               1421                 :                :                             bool strict_names)
                               1422                 :                : {
                               1423                 :                :     PQExpBuffer query;
                               1424                 :                :     PGresult   *res;
                               1425                 :                :     SimpleStringListCell *cell;
                               1426                 :                :     int         i;
                               1427                 :                : 
 6397 tgl@sss.pgh.pa.us        1428         [ +  + ]:            181 :     if (patterns->head == NULL)
                               1429                 :            162 :         return;                 /* nothing to do */
                               1430                 :                : 
                               1431                 :             19 :     query = createPQExpBuffer();
                               1432                 :                : 
                               1433                 :                :     /*
                               1434                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1435                 :                :      * duplicate entries in the OID list, but we don't care.
                               1436                 :                :      */
                               1437                 :                : 
                               1438         [ +  + ]:             32 :     for (cell = patterns->head; cell; cell = cell->next)
                               1439                 :                :     {
                               1440                 :                :         PQExpBufferData dbbuf;
                               1441                 :                :         int         dotcnt;
                               1442                 :                : 
 1746 drowley@postgresql.o     1443                 :             19 :         appendPQExpBufferStr(query,
                               1444                 :                :                              "SELECT oid FROM pg_catalog.pg_namespace n\n");
  725 rhaas@postgresql.org     1445                 :             19 :         initPQExpBuffer(&dbbuf);
 4441                          1446                 :             19 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1447                 :                :                               false, NULL, "n.nspname", NULL, NULL, &dbbuf,
                               1448                 :                :                               &dotcnt);
  725                          1449         [ +  + ]:             19 :         if (dotcnt > 1)
                               1450                 :              2 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1451                 :                :                      cell->val);
                               1452         [ +  + ]:             17 :         else if (dotcnt == 1)
                               1453                 :              3 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1454                 :             14 :         termPQExpBuffer(&dbbuf);
                               1455                 :                : 
 3135 teodor@sigaev.ru         1456                 :             14 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1457   [ +  +  +  - ]:             14 :         if (strict_names && PQntuples(res) == 0)
  737 tgl@sss.pgh.pa.us        1458                 :              1 :             pg_fatal("no matching schemas were found for pattern \"%s\"", cell->val);
                               1459                 :                : 
 3135 teodor@sigaev.ru         1460         [ +  + ]:             25 :         for (i = 0; i < PQntuples(res); i++)
                               1461                 :                :         {
                               1462                 :             12 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1463                 :                :         }
                               1464                 :                : 
                               1465                 :             13 :         PQclear(res);
                               1466                 :             13 :         resetPQExpBuffer(query);
                               1467                 :                :     }
                               1468                 :                : 
 6397 tgl@sss.pgh.pa.us        1469                 :             13 :     destroyPQExpBuffer(query);
                               1470                 :                : }
                               1471                 :                : 
                               1472                 :                : /*
                               1473                 :                :  * Find the OIDs of all extensions matching the given list of patterns,
                               1474                 :                :  * and append them to the given OID list.
                               1475                 :                :  */
                               1476                 :                : static void
 1110 michael@paquier.xyz      1477                 :            161 : expand_extension_name_patterns(Archive *fout,
                               1478                 :                :                                SimpleStringList *patterns,
                               1479                 :                :                                SimpleOidList *oids,
                               1480                 :                :                                bool strict_names)
                               1481                 :                : {
                               1482                 :                :     PQExpBuffer query;
                               1483                 :                :     PGresult   *res;
                               1484                 :                :     SimpleStringListCell *cell;
                               1485                 :                :     int         i;
                               1486                 :                : 
                               1487         [ +  + ]:            161 :     if (patterns->head == NULL)
 1110 michael@paquier.xyz      1488                 :GBC         154 :         return;                 /* nothing to do */
                               1489                 :                : 
 1110 michael@paquier.xyz      1490                 :CBC           7 :     query = createPQExpBuffer();
                               1491                 :                : 
                               1492                 :                :     /*
                               1493                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1494                 :                :      * duplicate entries in the OID list, but we don't care.
                               1495                 :                :      */
                               1496         [ +  + ]:             14 :     for (cell = patterns->head; cell; cell = cell->next)
                               1497                 :                :     {
                               1498                 :                :         int         dotcnt;
                               1499                 :                : 
                               1500                 :              7 :         appendPQExpBufferStr(query,
                               1501                 :                :                              "SELECT oid FROM pg_catalog.pg_extension e\n");
                               1502                 :              7 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1503                 :                :                               false, NULL, "e.extname", NULL, NULL, NULL,
                               1504                 :                :                               &dotcnt);
  725 rhaas@postgresql.org     1505         [ -  + ]:              7 :         if (dotcnt > 0)
  725 rhaas@postgresql.org     1506                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1507                 :                :                      cell->val);
                               1508                 :                : 
 1110 michael@paquier.xyz      1509                 :CBC           7 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1510   [ -  +  -  - ]:              7 :         if (strict_names && PQntuples(res) == 0)
  737 tgl@sss.pgh.pa.us        1511                 :UBC           0 :             pg_fatal("no matching extensions were found for pattern \"%s\"", cell->val);
                               1512                 :                : 
 1110 michael@paquier.xyz      1513         [ +  + ]:CBC          13 :         for (i = 0; i < PQntuples(res); i++)
                               1514                 :                :         {
                               1515                 :              6 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1516                 :                :         }
                               1517                 :                : 
                               1518                 :              7 :         PQclear(res);
                               1519                 :              7 :         resetPQExpBuffer(query);
                               1520                 :                :     }
                               1521                 :                : 
                               1522                 :              7 :     destroyPQExpBuffer(query);
                               1523                 :                : }
                               1524                 :                : 
                               1525                 :                : /*
                               1526                 :                :  * Find the OIDs of all foreign servers matching the given list of patterns,
                               1527                 :                :  * and append them to the given OID list.
                               1528                 :                :  */
                               1529                 :                : static void
 1481 alvherre@alvh.no-ip.     1530                 :            158 : expand_foreign_server_name_patterns(Archive *fout,
                               1531                 :                :                                     SimpleStringList *patterns,
                               1532                 :                :                                     SimpleOidList *oids)
                               1533                 :                : {
                               1534                 :                :     PQExpBuffer query;
                               1535                 :                :     PGresult   *res;
                               1536                 :                :     SimpleStringListCell *cell;
                               1537                 :                :     int         i;
                               1538                 :                : 
                               1539         [ +  + ]:            158 :     if (patterns->head == NULL)
                               1540                 :            155 :         return;                 /* nothing to do */
                               1541                 :                : 
                               1542                 :              3 :     query = createPQExpBuffer();
                               1543                 :                : 
                               1544                 :                :     /*
                               1545                 :                :      * The loop below runs multiple SELECTs might sometimes result in
                               1546                 :                :      * duplicate entries in the OID list, but we don't care.
                               1547                 :                :      */
                               1548                 :                : 
                               1549         [ +  + ]:              5 :     for (cell = patterns->head; cell; cell = cell->next)
                               1550                 :                :     {
                               1551                 :                :         int         dotcnt;
                               1552                 :                : 
 1277 drowley@postgresql.o     1553                 :              3 :         appendPQExpBufferStr(query,
                               1554                 :                :                              "SELECT oid FROM pg_catalog.pg_foreign_server s\n");
 1481 alvherre@alvh.no-ip.     1555                 :              3 :         processSQLNamePattern(GetConnection(fout), query, cell->val, false,
                               1556                 :                :                               false, NULL, "s.srvname", NULL, NULL, NULL,
                               1557                 :                :                               &dotcnt);
  725 rhaas@postgresql.org     1558         [ -  + ]:              3 :         if (dotcnt > 0)
  725 rhaas@postgresql.org     1559                 :UBC           0 :             pg_fatal("improper qualified name (too many dotted names): %s",
                               1560                 :                :                      cell->val);
                               1561                 :                : 
 1481 alvherre@alvh.no-ip.     1562                 :CBC           3 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               1563         [ +  + ]:              3 :         if (PQntuples(res) == 0)
  737 tgl@sss.pgh.pa.us        1564                 :GBC           1 :             pg_fatal("no matching foreign servers were found for pattern \"%s\"", cell->val);
                               1565                 :                : 
 1481 alvherre@alvh.no-ip.     1566         [ +  + ]:CBC           4 :         for (i = 0; i < PQntuples(res); i++)
                               1567                 :              2 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1568                 :                : 
                               1569                 :              2 :         PQclear(res);
                               1570                 :              2 :         resetPQExpBuffer(query);
                               1571                 :                :     }
                               1572                 :                : 
                               1573                 :              2 :     destroyPQExpBuffer(query);
                               1574                 :                : }
                               1575                 :                : 
                               1576                 :                : /*
                               1577                 :                :  * Find the OIDs of all tables matching the given list of patterns,
                               1578                 :                :  * and append them to the given OID list. See also expand_dbname_patterns()
                               1579                 :                :  * in pg_dumpall.c
                               1580                 :                :  */
                               1581                 :                : static void
 4450 rhaas@postgresql.org     1582                 :            957 : expand_table_name_patterns(Archive *fout,
                               1583                 :                :                            SimpleStringList *patterns, SimpleOidList *oids,
                               1584                 :                :                            bool strict_names, bool with_child_tables)
                               1585                 :                : {
                               1586                 :                :     PQExpBuffer query;
                               1587                 :                :     PGresult   *res;
                               1588                 :                :     SimpleStringListCell *cell;
                               1589                 :                :     int         i;
                               1590                 :                : 
 6397 tgl@sss.pgh.pa.us        1591         [ +  + ]:            957 :     if (patterns->head == NULL)
                               1592                 :            928 :         return;                 /* nothing to do */
                               1593                 :                : 
                               1594                 :             29 :     query = createPQExpBuffer();
                               1595                 :                : 
                               1596                 :                :     /*
                               1597                 :                :      * this might sometimes result in duplicate entries in the OID list, but
                               1598                 :                :      * we don't care.
                               1599                 :                :      */
                               1600                 :                : 
                               1601         [ +  + ]:             59 :     for (cell = patterns->head; cell; cell = cell->next)
                               1602                 :                :     {
                               1603                 :                :         PQExpBufferData dbbuf;
                               1604                 :                :         int         dotcnt;
                               1605                 :                : 
                               1606                 :                :         /*
                               1607                 :                :          * Query must remain ABSOLUTELY devoid of unqualified names.  This
                               1608                 :                :          * would be unnecessary given a pg_table_is_visible() variant taking a
                               1609                 :                :          * search_path argument.
                               1610                 :                :          *
                               1611                 :                :          * For with_child_tables, we start with the basic query's results and
                               1612                 :                :          * recursively search the inheritance tree to add child tables.
                               1613                 :                :          */
  397                          1614         [ +  + ]:             35 :         if (with_child_tables)
                               1615                 :                :         {
                               1616                 :              6 :             appendPQExpBuffer(query, "WITH RECURSIVE partition_tree (relid) AS (\n");
                               1617                 :                :         }
                               1618                 :                : 
 6397                          1619                 :             35 :         appendPQExpBuffer(query,
                               1620                 :                :                           "SELECT c.oid"
                               1621                 :                :                           "\nFROM pg_catalog.pg_class c"
                               1622                 :                :                           "\n     LEFT JOIN pg_catalog.pg_namespace n"
                               1623                 :                :                           "\n     ON n.oid OPERATOR(pg_catalog.=) c.relnamespace"
                               1624                 :                :                           "\nWHERE c.relkind OPERATOR(pg_catalog.=) ANY"
                               1625                 :                :                           "\n    (array['%c', '%c', '%c', '%c', '%c', '%c'])\n",
                               1626                 :                :                           RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
                               1627                 :                :                           RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE,
                               1628                 :                :                           RELKIND_PARTITIONED_TABLE);
  725 rhaas@postgresql.org     1629                 :             35 :         initPQExpBuffer(&dbbuf);
 4441                          1630                 :             35 :         processSQLNamePattern(GetConnection(fout), query, cell->val, true,
                               1631                 :                :                               false, "n.nspname", "c.relname", NULL,
                               1632                 :                :                               "pg_catalog.pg_table_is_visible(c.oid)", &dbbuf,
                               1633                 :                :                               &dotcnt);
  725                          1634         [ +  + ]:             35 :         if (dotcnt > 2)
                               1635                 :              1 :             pg_fatal("improper relation name (too many dotted names): %s",
                               1636                 :                :                      cell->val);
                               1637         [ +  + ]:             34 :         else if (dotcnt == 2)
                               1638                 :              2 :             prohibit_crossdb_refs(GetConnection(fout), dbbuf.data, cell->val);
                               1639                 :             32 :         termPQExpBuffer(&dbbuf);
                               1640                 :                : 
  397 tgl@sss.pgh.pa.us        1641         [ +  + ]:             32 :         if (with_child_tables)
                               1642                 :                :         {
                               1643                 :              6 :             appendPQExpBuffer(query, "UNION"
                               1644                 :                :                               "\nSELECT i.inhrelid"
                               1645                 :                :                               "\nFROM partition_tree p"
                               1646                 :                :                               "\n     JOIN pg_catalog.pg_inherits i"
                               1647                 :                :                               "\n     ON p.relid OPERATOR(pg_catalog.=) i.inhparent"
                               1648                 :                :                               "\n)"
                               1649                 :                :                               "\nSELECT relid FROM partition_tree");
                               1650                 :                :         }
                               1651                 :                : 
 2239 noah@leadboat.com        1652                 :             32 :         ExecuteSqlStatement(fout, "RESET search_path");
 3135 teodor@sigaev.ru         1653                 :             32 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 2239 noah@leadboat.com        1654                 :             32 :         PQclear(ExecuteSqlQueryForSingleRow(fout,
                               1655                 :                :                                             ALWAYS_SECURE_SEARCH_PATH_SQL));
 3135 teodor@sigaev.ru         1656   [ +  +  +  + ]:             32 :         if (strict_names && PQntuples(res) == 0)
  737 tgl@sss.pgh.pa.us        1657                 :              2 :             pg_fatal("no matching tables were found for pattern \"%s\"", cell->val);
                               1658                 :                : 
 3135 teodor@sigaev.ru         1659         [ +  + ]:             74 :         for (i = 0; i < PQntuples(res); i++)
                               1660                 :                :         {
                               1661                 :             44 :             simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
                               1662                 :                :         }
                               1663                 :                : 
                               1664                 :             30 :         PQclear(res);
                               1665                 :             30 :         resetPQExpBuffer(query);
                               1666                 :                :     }
                               1667                 :                : 
 6397 tgl@sss.pgh.pa.us        1668                 :             24 :     destroyPQExpBuffer(query);
                               1669                 :                : }
                               1670                 :                : 
                               1671                 :                : /*
                               1672                 :                :  * Verifies that the connected database name matches the given database name,
                               1673                 :                :  * and if not, dies with an error about the given pattern.
                               1674                 :                :  *
                               1675                 :                :  * The 'dbname' argument should be a literal name parsed from 'pattern'.
                               1676                 :                :  */
                               1677                 :                : static void
  725 rhaas@postgresql.org     1678                 :              5 : prohibit_crossdb_refs(PGconn *conn, const char *dbname, const char *pattern)
                               1679                 :                : {
                               1680                 :                :     const char *db;
                               1681                 :                : 
                               1682                 :              5 :     db = PQdb(conn);
                               1683         [ -  + ]:              5 :     if (db == NULL)
  725 rhaas@postgresql.org     1684                 :UBC           0 :         pg_fatal("You are currently not connected to a database.");
                               1685                 :                : 
  725 rhaas@postgresql.org     1686         [ +  - ]:CBC           5 :     if (strcmp(db, dbname) != 0)
                               1687                 :              5 :         pg_fatal("cross-database references are not implemented: %s",
                               1688                 :                :                  pattern);
  725 rhaas@postgresql.org     1689                 :UBC           0 : }
                               1690                 :                : 
                               1691                 :                : /*
                               1692                 :                :  * checkExtensionMembership
                               1693                 :                :  *      Determine whether object is an extension member, and if so,
                               1694                 :                :  *      record an appropriate dependency and set the object's dump flag.
                               1695                 :                :  *
                               1696                 :                :  * It's important to call this for each object that could be an extension
                               1697                 :                :  * member.  Generally, we integrate this with determining the object's
                               1698                 :                :  * to-be-dumped-ness, since extension membership overrides other rules for that.
                               1699                 :                :  *
                               1700                 :                :  * Returns true if object is an extension member, else false.
                               1701                 :                :  */
                               1702                 :                : static bool
 2930 sfrost@snowman.net       1703                 :CBC      582840 : checkExtensionMembership(DumpableObject *dobj, Archive *fout)
                               1704                 :                : {
 3014 tgl@sss.pgh.pa.us        1705                 :         582840 :     ExtensionInfo *ext = findOwningExtension(dobj->catId);
                               1706                 :                : 
                               1707         [ +  + ]:         582840 :     if (ext == NULL)
                               1708                 :         582143 :         return false;
                               1709                 :                : 
                               1710                 :            697 :     dobj->ext_member = true;
                               1711                 :                : 
                               1712                 :                :     /* Record dependency so that getDependencies needn't deal with that */
                               1713                 :            697 :     addObjectDependency(dobj, ext->dobj.dumpId);
                               1714                 :                : 
                               1715                 :                :     /*
                               1716                 :                :      * In 9.6 and above, mark the member object to have any non-initial ACLs
                               1717                 :                :      * dumped.  (Any initial ACLs will be removed later, using data from
                               1718                 :                :      * pg_init_privs, so that we'll dump only the delta from the extension's
                               1719                 :                :      * initial setup.)
                               1720                 :                :      *
                               1721                 :                :      * Prior to 9.6, we do not include any extension member components.
                               1722                 :                :      *
                               1723                 :                :      * In binary upgrades, we still dump all components of the members
                               1724                 :                :      * individually, since the idea is to exactly reproduce the database
                               1725                 :                :      * contents rather than replace the extension contents with something
                               1726                 :                :      * different.
                               1727                 :                :      *
                               1728                 :                :      * Note: it might be interesting someday to implement storage and delta
                               1729                 :                :      * dumping of extension members' RLS policies and/or security labels.
                               1730                 :                :      * However there is a pitfall for RLS policies: trying to dump them
                               1731                 :                :      * requires getting a lock on their tables, and the calling user might not
                               1732                 :                :      * have privileges for that.  We need no lock to examine a table's ACLs,
                               1733                 :                :      * so the current feature doesn't have a problem of that sort.
                               1734                 :                :      */
 2900 sfrost@snowman.net       1735         [ +  + ]:            697 :     if (fout->dopt->binary_upgrade)
 3014 tgl@sss.pgh.pa.us        1736                 :             76 :         dobj->dump = ext->dobj.dump;
                               1737                 :                :     else
                               1738                 :                :     {
 2900 sfrost@snowman.net       1739         [ -  + ]:            621 :         if (fout->remoteVersion < 90600)
 2900 sfrost@snowman.net       1740                 :UBC           0 :             dobj->dump = DUMP_COMPONENT_NONE;
                               1741                 :                :         else
  153 tgl@sss.pgh.pa.us        1742                 :CBC         621 :             dobj->dump = ext->dobj.dump_contains & (DUMP_COMPONENT_ACL);
                               1743                 :                :     }
                               1744                 :                : 
 3014                          1745                 :            697 :     return true;
                               1746                 :                : }
                               1747                 :                : 
                               1748                 :                : /*
                               1749                 :                :  * selectDumpableNamespace: policy-setting subroutine
                               1750                 :                :  *      Mark a namespace as to be dumped or not
                               1751                 :                :  */
                               1752                 :                : static void
 2930 sfrost@snowman.net       1753                 :           1152 : selectDumpableNamespace(NamespaceInfo *nsinfo, Archive *fout)
                               1754                 :                : {
                               1755                 :                :     /*
                               1756                 :                :      * DUMP_COMPONENT_DEFINITION typically implies a CREATE SCHEMA statement
                               1757                 :                :      * and (for --clean) a DROP SCHEMA statement.  (In the absence of
                               1758                 :                :      * DUMP_COMPONENT_DEFINITION, this value is irrelevant.)
                               1759                 :                :      */
 1021 noah@leadboat.com        1760                 :           1152 :     nsinfo->create = true;
                               1761                 :                : 
                               1762                 :                :     /*
                               1763                 :                :      * If specific tables are being dumped, do not dump any complete
                               1764                 :                :      * namespaces. If specific namespaces are being dumped, dump just those
                               1765                 :                :      * namespaces. Otherwise, dump all non-system namespaces.
                               1766                 :                :      */
 6397 tgl@sss.pgh.pa.us        1767         [ +  + ]:           1152 :     if (table_include_oids.head != NULL)
 2930 sfrost@snowman.net       1768                 :             50 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
 6397 tgl@sss.pgh.pa.us        1769         [ +  + ]:           1102 :     else if (schema_include_oids.head != NULL)
 2930 sfrost@snowman.net       1770                 :             49 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump =
                               1771                 :             49 :             simple_oid_list_member(&schema_include_oids,
                               1772                 :                :                                    nsinfo->dobj.catId.oid) ?
                               1773         [ +  + ]:             49 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               1774         [ +  - ]:           1053 :     else if (fout->remoteVersion >= 90600 &&
 2775 tgl@sss.pgh.pa.us        1775         [ +  + ]:           1053 :              strcmp(nsinfo->dobj.name, "pg_catalog") == 0)
                               1776                 :                :     {
                               1777                 :                :         /*
                               1778                 :                :          * In 9.6 and above, we dump out any ACLs defined in pg_catalog, if
                               1779                 :                :          * they are interesting (and not the original ACLs which were set at
                               1780                 :                :          * initdb time, see pg_init_privs).
                               1781                 :                :          */
 2930 sfrost@snowman.net       1782                 :            136 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ACL;
                               1783                 :                :     }
 6397 tgl@sss.pgh.pa.us        1784         [ +  + ]:            917 :     else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 ||
                               1785         [ +  + ]:            417 :              strcmp(nsinfo->dobj.name, "information_schema") == 0)
                               1786                 :                :     {
                               1787                 :                :         /* Other system schemas don't get dumped */
 2930 sfrost@snowman.net       1788                 :            636 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               1789                 :                :     }
 2271 tgl@sss.pgh.pa.us        1790         [ +  + ]:            281 :     else if (strcmp(nsinfo->dobj.name, "public") == 0)
                               1791                 :                :     {
                               1792                 :                :         /*
                               1793                 :                :          * The public schema is a strange beast that sits in a sort of
                               1794                 :                :          * no-mans-land between being a system object and a user object.
                               1795                 :                :          * CREATE SCHEMA would fail, so its DUMP_COMPONENT_DEFINITION is just
                               1796                 :                :          * a comment and an indication of ownership.  If the owner is the
                               1797                 :                :          * default, omit that superfluous DUMP_COMPONENT_DEFINITION.  Before
                               1798                 :                :          * v15, the default owner was BOOTSTRAP_SUPERUSERID.
                               1799                 :                :          */
 1021 noah@leadboat.com        1800                 :            132 :         nsinfo->create = false;
                               1801                 :            132 :         nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
  948                          1802         [ +  + ]:            132 :         if (nsinfo->nspowner == ROLE_PG_DATABASE_OWNER)
 1021                          1803                 :             89 :             nsinfo->dobj.dump &= ~DUMP_COMPONENT_DEFINITION;
 2271 tgl@sss.pgh.pa.us        1804                 :            132 :         nsinfo->dobj.dump_contains = DUMP_COMPONENT_ALL;
                               1805                 :                : 
                               1806                 :                :         /*
                               1807                 :                :          * Also, make like it has a comment even if it doesn't; this is so
                               1808                 :                :          * that we'll emit a command to drop the comment, if appropriate.
                               1809                 :                :          * (Without this, we'd not call dumpCommentExtended for it.)
                               1810                 :                :          */
  860                          1811                 :            132 :         nsinfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                               1812                 :                :     }
                               1813                 :                :     else
 2930 sfrost@snowman.net       1814                 :            149 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_ALL;
                               1815                 :                : 
                               1816                 :                :     /*
                               1817                 :                :      * In any case, a namespace can be excluded by an exclusion switch
                               1818                 :                :      */
                               1819   [ +  +  +  + ]:           1578 :     if (nsinfo->dobj.dump_contains &&
 6397 tgl@sss.pgh.pa.us        1820                 :            426 :         simple_oid_list_member(&schema_exclude_oids,
                               1821                 :                :                                nsinfo->dobj.catId.oid))
 2930 sfrost@snowman.net       1822                 :              3 :         nsinfo->dobj.dump_contains = nsinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               1823                 :                : 
                               1824                 :                :     /*
                               1825                 :                :      * If the schema belongs to an extension, allow extension membership to
                               1826                 :                :      * override the dump decision for the schema itself.  However, this does
                               1827                 :                :      * not change dump_contains, so this won't change what we do with objects
                               1828                 :                :      * within the schema.  (If they belong to the extension, they'll get
                               1829                 :                :      * suppressed by it, otherwise not.)
                               1830                 :                :      */
 2775 tgl@sss.pgh.pa.us        1831                 :           1152 :     (void) checkExtensionMembership(&nsinfo->dobj, fout);
 6397                          1832                 :           1152 : }
                               1833                 :                : 
                               1834                 :                : /*
                               1835                 :                :  * selectDumpableTable: policy-setting subroutine
                               1836                 :                :  *      Mark a table as to be dumped or not
                               1837                 :                :  */
                               1838                 :                : static void
 2930 sfrost@snowman.net       1839                 :          39371 : selectDumpableTable(TableInfo *tbinfo, Archive *fout)
                               1840                 :                : {
                               1841         [ +  + ]:          39371 :     if (checkExtensionMembership(&tbinfo->dobj, fout))
 3014 tgl@sss.pgh.pa.us        1842                 :            225 :         return;                 /* extension membership overrides all else */
                               1843                 :                : 
                               1844                 :                :     /*
                               1845                 :                :      * If specific tables are being dumped, dump just those tables; else, dump
                               1846                 :                :      * according to the parent namespace's dump flag.
                               1847                 :                :      */
 6397                          1848         [ +  + ]:          39146 :     if (table_include_oids.head != NULL)
                               1849                 :           5052 :         tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
                               1850                 :                :                                                    tbinfo->dobj.catId.oid) ?
 2930 sfrost@snowman.net       1851         [ +  + ]:           2526 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               1852                 :                :     else
                               1853                 :          36620 :         tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump_contains;
                               1854                 :                : 
                               1855                 :                :     /*
                               1856                 :                :      * In any case, a table can be excluded by an exclusion switch
                               1857                 :                :      */
 6397 tgl@sss.pgh.pa.us        1858   [ +  +  +  + ]:          64442 :     if (tbinfo->dobj.dump &&
                               1859                 :          25296 :         simple_oid_list_member(&table_exclude_oids,
                               1860                 :                :                                tbinfo->dobj.catId.oid))
 2930 sfrost@snowman.net       1861                 :             12 :         tbinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               1862                 :                : }
                               1863                 :                : 
                               1864                 :                : /*
                               1865                 :                :  * selectDumpableType: policy-setting subroutine
                               1866                 :                :  *      Mark a type as to be dumped or not
                               1867                 :                :  *
                               1868                 :                :  * If it's a table's rowtype or an autogenerated array type, we also apply a
                               1869                 :                :  * special type code to facilitate sorting into the desired order.  (We don't
                               1870                 :                :  * want to consider those to be ordinary types because that would bring tables
                               1871                 :                :  * up into the datatype part of the dump order.)  We still set the object's
                               1872                 :                :  * dump flag; that's not going to cause the dummy type to be dumped, but we
                               1873                 :                :  * need it so that casts involving such types will be dumped correctly -- see
                               1874                 :                :  * dumpCast.  This means the flag should be set the same as for the underlying
                               1875                 :                :  * object (the table or base type).
                               1876                 :                :  */
                               1877                 :                : static void
                               1878                 :         108802 : selectDumpableType(TypeInfo *tyinfo, Archive *fout)
                               1879                 :                : {
                               1880                 :                :     /* skip complex types, except for standalone composite types */
 5226 bruce@momjian.us         1881         [ +  + ]:         108802 :     if (OidIsValid(tyinfo->typrelid) &&
                               1882         [ +  + ]:          38749 :         tyinfo->typrelkind != RELKIND_COMPOSITE_TYPE)
                               1883                 :                :     {
 4562 tgl@sss.pgh.pa.us        1884                 :          38598 :         TableInfo  *tytable = findTableByOid(tyinfo->typrelid);
                               1885                 :                : 
 5226 bruce@momjian.us         1886                 :          38598 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
 4562 tgl@sss.pgh.pa.us        1887         [ +  - ]:          38598 :         if (tytable != NULL)
                               1888                 :          38598 :             tyinfo->dobj.dump = tytable->dobj.dump;
                               1889                 :                :         else
 2930 sfrost@snowman.net       1890                 :UBC           0 :             tyinfo->dobj.dump = DUMP_COMPONENT_NONE;
 4562 tgl@sss.pgh.pa.us        1891                 :CBC       38598 :         return;
                               1892                 :                :     }
                               1893                 :                : 
                               1894                 :                :     /* skip auto-generated array and multirange types */
 1211 akorotkov@postgresql     1895   [ +  +  +  + ]:          70204 :     if (tyinfo->isArray || tyinfo->isMultirange)
                               1896                 :                :     {
 5226 bruce@momjian.us         1897                 :          53170 :         tyinfo->dobj.objType = DO_DUMMY_TYPE;
                               1898                 :                : 
                               1899                 :                :         /*
                               1900                 :                :          * Fall through to set the dump flag; we assume that the subsequent
                               1901                 :                :          * rules will do the same thing as they would for the array's base
                               1902                 :                :          * type or multirange's range type.  (We cannot reliably look up the
                               1903                 :                :          * base type here, since getTypes may not have processed it yet.)
                               1904                 :                :          */
                               1905                 :                :     }
                               1906                 :                : 
 2930 sfrost@snowman.net       1907         [ +  + ]:          70204 :     if (checkExtensionMembership(&tyinfo->dobj, fout))
 3014 tgl@sss.pgh.pa.us        1908                 :            150 :         return;                 /* extension membership overrides all else */
                               1909                 :                : 
                               1910                 :                :     /* Dump based on if the contents of the namespace are being dumped */
 2930 sfrost@snowman.net       1911                 :          70054 :     tyinfo->dobj.dump = tyinfo->dobj.namespace->dobj.dump_contains;
                               1912                 :                : }
                               1913                 :                : 
                               1914                 :                : /*
                               1915                 :                :  * selectDumpableDefaultACL: policy-setting subroutine
                               1916                 :                :  *      Mark a default ACL as to be dumped or not
                               1917                 :                :  *
                               1918                 :                :  * For per-schema default ACLs, dump if the schema is to be dumped.
                               1919                 :                :  * Otherwise dump if we are dumping "everything".  Note that dataOnly
                               1920                 :                :  * and aclsSkip are checked separately.
                               1921                 :                :  */
                               1922                 :                : static void
 3014 tgl@sss.pgh.pa.us        1923                 :            184 : selectDumpableDefaultACL(DefaultACLInfo *dinfo, DumpOptions *dopt)
                               1924                 :                : {
                               1925                 :                :     /* Default ACLs can't be extension members */
                               1926                 :                : 
 5305                          1927         [ +  + ]:            184 :     if (dinfo->dobj.namespace)
                               1928                 :                :         /* default ACLs are considered part of the namespace */
 2900 sfrost@snowman.net       1929                 :             92 :         dinfo->dobj.dump = dinfo->dobj.namespace->dobj.dump_contains;
                               1930                 :                :     else
 2930                          1931                 :             92 :         dinfo->dobj.dump = dopt->include_everything ?
                               1932         [ +  + ]:             92 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
 5305 tgl@sss.pgh.pa.us        1933                 :            184 : }
                               1934                 :                : 
                               1935                 :                : /*
                               1936                 :                :  * selectDumpableCast: policy-setting subroutine
                               1937                 :                :  *      Mark a cast as to be dumped or not
                               1938                 :                :  *
                               1939                 :                :  * Casts do not belong to any particular namespace (since they haven't got
                               1940                 :                :  * names), nor do they have identifiable owners.  To distinguish user-defined
                               1941                 :                :  * casts from built-in ones, we must resort to checking whether the cast's
                               1942                 :                :  * OID is in the range reserved for initdb.
                               1943                 :                :  */
                               1944                 :                : static void
 2930 sfrost@snowman.net       1945                 :          34641 : selectDumpableCast(CastInfo *cast, Archive *fout)
                               1946                 :                : {
                               1947         [ -  + ]:          34641 :     if (checkExtensionMembership(&cast->dobj, fout))
 3014 tgl@sss.pgh.pa.us        1948                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               1949                 :                : 
                               1950                 :                :     /*
                               1951                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb casts, but they do not
                               1952                 :                :      * support ACLs currently.
                               1953                 :                :      */
 2671 sfrost@snowman.net       1954         [ +  + ]:CBC       34641 :     if (cast->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 2930                          1955                 :          34565 :         cast->dobj.dump = DUMP_COMPONENT_NONE;
                               1956                 :                :     else
                               1957                 :             76 :         cast->dobj.dump = fout->dopt->include_everything ?
                               1958         [ +  + ]:             76 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               1959                 :                : }
                               1960                 :                : 
                               1961                 :                : /*
                               1962                 :                :  * selectDumpableProcLang: policy-setting subroutine
                               1963                 :                :  *      Mark a procedural language as to be dumped or not
                               1964                 :                :  *
                               1965                 :                :  * Procedural languages do not belong to any particular namespace.  To
                               1966                 :                :  * identify built-in languages, we must resort to checking whether the
                               1967                 :                :  * language's OID is in the range reserved for initdb.
                               1968                 :                :  */
                               1969                 :                : static void
                               1970                 :            201 : selectDumpableProcLang(ProcLangInfo *plang, Archive *fout)
                               1971                 :                : {
                               1972         [ +  + ]:            201 :     if (checkExtensionMembership(&plang->dobj, fout))
 3014 tgl@sss.pgh.pa.us        1973                 :            155 :         return;                 /* extension membership overrides all else */
                               1974                 :                : 
                               1975                 :                :     /*
                               1976                 :                :      * Only include procedural languages when we are dumping everything.
                               1977                 :                :      *
                               1978                 :                :      * For from-initdb procedural languages, only include ACLs, as we do for
                               1979                 :                :      * the pg_catalog namespace.  We need this because procedural languages do
                               1980                 :                :      * not live in any namespace.
                               1981                 :                :      */
 2900 sfrost@snowman.net       1982         [ +  + ]:             46 :     if (!fout->dopt->include_everything)
 2930                          1983                 :              8 :         plang->dobj.dump = DUMP_COMPONENT_NONE;
                               1984                 :                :     else
                               1985                 :                :     {
 2671                          1986         [ -  + ]:             38 :         if (plang->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 2900 sfrost@snowman.net       1987                 :UBC           0 :             plang->dobj.dump = fout->remoteVersion < 90600 ?
                               1988         [ #  # ]:              0 :                 DUMP_COMPONENT_NONE : DUMP_COMPONENT_ACL;
                               1989                 :                :         else
 2900 sfrost@snowman.net       1990                 :CBC          38 :             plang->dobj.dump = DUMP_COMPONENT_ALL;
                               1991                 :                :     }
                               1992                 :                : }
                               1993                 :                : 
                               1994                 :                : /*
                               1995                 :                :  * selectDumpableAccessMethod: policy-setting subroutine
                               1996                 :                :  *      Mark an access method as to be dumped or not
                               1997                 :                :  *
                               1998                 :                :  * Access methods do not belong to any particular namespace.  To identify
                               1999                 :                :  * built-in access methods, we must resort to checking whether the
                               2000                 :                :  * method's OID is in the range reserved for initdb.
                               2001                 :                :  */
                               2002                 :                : static void
 2930                          2003                 :           1207 : selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout)
                               2004                 :                : {
                               2005         [ +  + ]:           1207 :     if (checkExtensionMembership(&method->dobj, fout))
 2944 alvherre@alvh.no-ip.     2006                 :             25 :         return;                 /* extension membership overrides all else */
                               2007                 :                : 
                               2008                 :                :     /*
                               2009                 :                :      * This would be DUMP_COMPONENT_ACL for from-initdb access methods, but
                               2010                 :                :      * they do not support ACLs currently.
                               2011                 :                :      */
 2671 sfrost@snowman.net       2012         [ +  + ]:           1182 :     if (method->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 2930                          2013                 :           1085 :         method->dobj.dump = DUMP_COMPONENT_NONE;
                               2014                 :                :     else
                               2015                 :             97 :         method->dobj.dump = fout->dopt->include_everything ?
                               2016         [ +  + ]:             97 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2017                 :                : }
                               2018                 :                : 
                               2019                 :                : /*
                               2020                 :                :  * selectDumpableExtension: policy-setting subroutine
                               2021                 :                :  *      Mark an extension as to be dumped or not
                               2022                 :                :  *
                               2023                 :                :  * Built-in extensions should be skipped except for checking ACLs, since we
                               2024                 :                :  * assume those will already be installed in the target database.  We identify
                               2025                 :                :  * such extensions by their having OIDs in the range reserved for initdb.
                               2026                 :                :  * We dump all user-added extensions by default.  No extensions are dumped
                               2027                 :                :  * if include_everything is false (i.e., a --schema or --table switch was
                               2028                 :                :  * given), except if --extension specifies a list of extensions to dump.
                               2029                 :                :  */
                               2030                 :                : static void
 3014 tgl@sss.pgh.pa.us        2031                 :            181 : selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt)
                               2032                 :                : {
                               2033                 :                :     /*
                               2034                 :                :      * Use DUMP_COMPONENT_ACL for built-in extensions, to allow users to
                               2035                 :                :      * change permissions on their member objects, if they wish to, and have
                               2036                 :                :      * those changes preserved.
                               2037                 :                :      */
 2271                          2038         [ +  + ]:            181 :     if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid)
 2900 sfrost@snowman.net       2039                 :            156 :         extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL;
                               2040                 :                :     else
                               2041                 :                :     {
                               2042                 :                :         /* check if there is a list of extensions to dump */
 1110 michael@paquier.xyz      2043         [ +  + ]:             25 :         if (extension_include_oids.head != NULL)
                               2044                 :              4 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2045                 :              4 :                 simple_oid_list_member(&extension_include_oids,
                               2046                 :                :                                        extinfo->dobj.catId.oid) ?
                               2047         [ +  + ]:              4 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2048                 :                :         else
                               2049                 :             21 :             extinfo->dobj.dump = extinfo->dobj.dump_contains =
                               2050                 :             21 :                 dopt->include_everything ?
                               2051         [ +  + ]:             21 :                 DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2052                 :                : 
                               2053                 :                :         /* check that the extension is not explicitly excluded */
   25 dean.a.rasheed@gmail     2054   [ +  +  +  + ]:GNC          46 :         if (extinfo->dobj.dump &&
                               2055                 :             21 :             simple_oid_list_member(&extension_exclude_oids,
                               2056                 :                :                                    extinfo->dobj.catId.oid))
                               2057                 :              2 :             extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_NONE;
                               2058                 :                :     }
 4790 tgl@sss.pgh.pa.us        2059                 :CBC         181 : }
                               2060                 :                : 
                               2061                 :                : /*
                               2062                 :                :  * selectDumpablePublicationObject: policy-setting subroutine
                               2063                 :                :  *      Mark a publication object as to be dumped or not
                               2064                 :                :  *
                               2065                 :                :  * A publication can have schemas and tables which have schemas, but those are
                               2066                 :                :  * ignored in decision making, because publications are only dumped when we are
                               2067                 :                :  * dumping everything.
                               2068                 :                :  */
                               2069                 :                : static void
  900 akapila@postgresql.o     2070                 :            353 : selectDumpablePublicationObject(DumpableObject *dobj, Archive *fout)
                               2071                 :                : {
 2581 peter_e@gmx.net          2072         [ -  + ]:            353 :     if (checkExtensionMembership(dobj, fout))
 2581 peter_e@gmx.net          2073                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2074                 :                : 
 2581 peter_e@gmx.net          2075                 :CBC         353 :     dobj->dump = fout->dopt->include_everything ?
                               2076         [ +  + ]:            353 :         DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2077                 :                : }
                               2078                 :                : 
                               2079                 :                : /*
                               2080                 :                :  * selectDumpableStatisticsObject: policy-setting subroutine
                               2081                 :                :  *      Mark an extended statistics object as to be dumped or not
                               2082                 :                :  *
                               2083                 :                :  * We dump an extended statistics object if the schema it's in and the table
                               2084                 :                :  * it's for are being dumped.  (This'll need more thought if statistics
                               2085                 :                :  * objects ever support cross-table stats.)
                               2086                 :                :  */
                               2087                 :                : static void
  107 tgl@sss.pgh.pa.us        2088                 :            158 : selectDumpableStatisticsObject(StatsExtInfo *sobj, Archive *fout)
                               2089                 :                : {
                               2090         [ -  + ]:            158 :     if (checkExtensionMembership(&sobj->dobj, fout))
  107 tgl@sss.pgh.pa.us        2091                 :UBC           0 :         return;                 /* extension membership overrides all else */
                               2092                 :                : 
  107 tgl@sss.pgh.pa.us        2093                 :CBC         158 :     sobj->dobj.dump = sobj->dobj.namespace->dobj.dump_contains;
                               2094         [ +  - ]:            158 :     if (sobj->stattable == NULL ||
                               2095         [ +  + ]:            158 :         !(sobj->stattable->dobj.dump & DUMP_COMPONENT_DEFINITION))
                               2096                 :             20 :         sobj->dobj.dump = DUMP_COMPONENT_NONE;
                               2097                 :                : }
                               2098                 :                : 
                               2099                 :                : /*
                               2100                 :                :  * selectDumpableObject: policy-setting subroutine
                               2101                 :                :  *      Mark a generic dumpable object as to be dumped or not
                               2102                 :                :  *
                               2103                 :                :  * Use this only for object types without a special-case routine above.
                               2104                 :                :  */
                               2105                 :                : static void
 2930 sfrost@snowman.net       2106                 :         435553 : selectDumpableObject(DumpableObject *dobj, Archive *fout)
                               2107                 :                : {
                               2108         [ +  + ]:         435553 :     if (checkExtensionMembership(dobj, fout))
 3014 tgl@sss.pgh.pa.us        2109                 :            117 :         return;                 /* extension membership overrides all else */
                               2110                 :                : 
                               2111                 :                :     /*
                               2112                 :                :      * Default policy is to dump if parent namespace is dumpable, or for
                               2113                 :                :      * non-namespace-associated items, dump if we're dumping "everything".
                               2114                 :                :      */
 6618                          2115         [ +  + ]:         435436 :     if (dobj->namespace)
 2930 sfrost@snowman.net       2116                 :         434869 :         dobj->dump = dobj->namespace->dobj.dump_contains;
                               2117                 :                :     else
                               2118                 :            567 :         dobj->dump = fout->dopt->include_everything ?
                               2119         [ +  + ]:            567 :             DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE;
                               2120                 :                : }
                               2121                 :                : 
                               2122                 :                : /*
                               2123                 :                :  *  Dump a table's contents for loading using the COPY command
                               2124                 :                :  *  - this routine is called by the Archiver when it wants the table
                               2125                 :                :  *    to be dumped.
                               2126                 :                :  */
                               2127                 :                : static int
 1159 peter@eisentraut.org     2128                 :           3479 : dumpTableData_copy(Archive *fout, const void *dcontext)
                               2129                 :                : {
 7435 tgl@sss.pgh.pa.us        2130                 :           3479 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2131                 :           3479 :     TableInfo  *tbinfo = tdinfo->tdtable;
 7347                          2132                 :           3479 :     const char *classname = tbinfo->dobj.name;
 8010                          2133                 :           3479 :     PQExpBuffer q = createPQExpBuffer();
                               2134                 :                : 
                               2135                 :                :     /*
                               2136                 :                :      * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
                               2137                 :                :      * which uses it already.
                               2138                 :                :      */
 4039 andrew@dunslane.net      2139                 :           3479 :     PQExpBuffer clistBuf = createPQExpBuffer();
 4441 rhaas@postgresql.org     2140                 :           3479 :     PGconn     *conn = GetConnection(fout);
                               2141                 :                :     PGresult   *res;
                               2142                 :                :     int         ret;
                               2143                 :                :     char       *copybuf;
                               2144                 :                :     const char *column_list;
                               2145                 :                : 
 1840 peter@eisentraut.org     2146                 :           3479 :     pg_log_info("dumping contents of table \"%s.%s\"",
                               2147                 :                :                 tbinfo->dobj.namespace->dobj.name, classname);
                               2148                 :                : 
                               2149                 :                :     /*
                               2150                 :                :      * Specify the column list explicitly so that we have no possibility of
                               2151                 :                :      * retrieving data in the wrong column order.  (The default column
                               2152                 :                :      * ordering of COPY will not be what we want in certain corner cases
                               2153                 :                :      * involving ADD COLUMN and inheritance.)
                               2154                 :                :      */
 2741 tgl@sss.pgh.pa.us        2155                 :           3479 :     column_list = fmtCopyColumnList(tbinfo, clistBuf);
                               2156                 :                : 
                               2157                 :                :     /*
                               2158                 :                :      * Use COPY (SELECT ...) TO when dumping a foreign table's data, and when
                               2159                 :                :      * a filter condition was specified.  For other cases a simple COPY
                               2160                 :                :      * suffices.
                               2161                 :                :      */
 1481 alvherre@alvh.no-ip.     2162   [ +  -  +  + ]:           3479 :     if (tdinfo->filtercond || tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                               2163                 :                :     {
 4814 tgl@sss.pgh.pa.us        2164                 :              1 :         appendPQExpBufferStr(q, "COPY (SELECT ");
                               2165                 :                :         /* klugery to get rid of parens in column list */
                               2166         [ +  - ]:              1 :         if (strlen(column_list) > 2)
                               2167                 :                :         {
                               2168                 :              1 :             appendPQExpBufferStr(q, column_list + 1);
                               2169                 :              1 :             q->data[q->len - 1] = ' ';
                               2170                 :                :         }
                               2171                 :                :         else
 4814 tgl@sss.pgh.pa.us        2172                 :UBC           0 :             appendPQExpBufferStr(q, "* ");
                               2173                 :                : 
                               2174                 :              0 :         appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
 2239 tgl@sss.pgh.pa.us        2175                 :CBC           1 :                           fmtQualifiedDumpable(tbinfo),
 1481 alvherre@alvh.no-ip.     2176         [ -  + ]:              1 :                           tdinfo->filtercond ? tdinfo->filtercond : "");
                               2177                 :                :     }
                               2178                 :                :     else
                               2179                 :                :     {
 7941 bruce@momjian.us         2180                 :           3478 :         appendPQExpBuffer(q, "COPY %s %s TO stdout;",
 2239 tgl@sss.pgh.pa.us        2181                 :           3478 :                           fmtQualifiedDumpable(tbinfo),
                               2182                 :                :                           column_list);
                               2183                 :                :     }
 4450 rhaas@postgresql.org     2184                 :           3479 :     res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
 6617 tgl@sss.pgh.pa.us        2185                 :           3478 :     PQclear(res);
 4039 andrew@dunslane.net      2186                 :           3478 :     destroyPQExpBuffer(clistBuf);
                               2187                 :                : 
                               2188                 :                :     for (;;)
                               2189                 :                :     {
 4441 rhaas@postgresql.org     2190                 :        1713857 :         ret = PQgetCopyData(conn, &copybuf, 0);
                               2191                 :                : 
 6617 tgl@sss.pgh.pa.us        2192         [ +  + ]:        1713857 :         if (ret < 0)
                               2193                 :           3478 :             break;              /* done or error */
                               2194                 :                : 
                               2195         [ +  - ]:        1710379 :         if (copybuf)
                               2196                 :                :         {
                               2197                 :        1710379 :             WriteData(fout, copybuf, ret);
                               2198                 :        1710379 :             PQfreemem(copybuf);
                               2199                 :                :         }
                               2200                 :                : 
                               2201                 :                :         /* ----------
                               2202                 :                :          * THROTTLE:
                               2203                 :                :          *
                               2204                 :                :          * There was considerable discussion in late July, 2000 regarding
                               2205                 :                :          * slowing down pg_dump when backing up large tables. Users with both
                               2206                 :                :          * slow & fast (multi-processor) machines experienced performance
                               2207                 :                :          * degradation when doing a backup.
                               2208                 :                :          *
                               2209                 :                :          * Initial attempts based on sleeping for a number of ms for each ms
                               2210                 :                :          * of work were deemed too complex, then a simple 'sleep in each loop'
                               2211                 :                :          * implementation was suggested. The latter failed because the loop
                               2212                 :                :          * was too tight. Finally, the following was implemented:
                               2213                 :                :          *
                               2214                 :                :          * If throttle is non-zero, then
                               2215                 :                :          *      See how long since the last sleep.
                               2216                 :                :          *      Work out how long to sleep (based on ratio).
                               2217                 :                :          *      If sleep is more than 100ms, then
                               2218                 :                :          *          sleep
                               2219                 :                :          *          reset timer
                               2220                 :                :          *      EndIf
                               2221                 :                :          * EndIf
                               2222                 :                :          *
                               2223                 :                :          * where the throttle value was the number of ms to sleep per ms of
                               2224                 :                :          * work. The calculation was done in each loop.
                               2225                 :                :          *
                               2226                 :                :          * Most of the hard work is done in the backend, and this solution
                               2227                 :                :          * still did not work particularly well: on slow machines, the ratio
                               2228                 :                :          * was 50:1, and on medium paced machines, 1:1, and on fast
                               2229                 :                :          * multi-processor machines, it had little or no effect, for reasons
                               2230                 :                :          * that were unclear.
                               2231                 :                :          *
                               2232                 :                :          * Further discussion ensued, and the proposal was dropped.
                               2233                 :                :          *
                               2234                 :                :          * For those people who want this feature, it can be implemented using
                               2235                 :                :          * gettimeofday in each loop, calculating the time since last sleep,
                               2236                 :                :          * multiplying that by the sleep ratio, then if the result is more
                               2237                 :                :          * than a preset 'minimum sleep time' (say 100ms), call the 'select'
                               2238                 :                :          * function to sleep for a subsecond period ie.
                               2239                 :                :          *
                               2240                 :                :          * select(0, NULL, NULL, NULL, &tvi);
                               2241                 :                :          *
                               2242                 :                :          * This will return after the interval specified in the structure tvi.
                               2243                 :                :          * Finally, call gettimeofday again to save the 'last sleep time'.
                               2244                 :                :          * ----------
                               2245                 :                :          */
                               2246                 :                :     }
 7910 peter_e@gmx.net          2247                 :           3478 :     archprintf(fout, "\\.\n\n\n");
                               2248                 :                : 
 6617 tgl@sss.pgh.pa.us        2249         [ -  + ]:           3478 :     if (ret == -2)
                               2250                 :                :     {
                               2251                 :                :         /* copy data transfer failed */
 1840 peter@eisentraut.org     2252                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname);
  737 tgl@sss.pgh.pa.us        2253                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2254                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 4441 rhaas@postgresql.org     2255                 :              0 :         exit_nicely(1);
                               2256                 :                :     }
                               2257                 :                : 
                               2258                 :                :     /* Check command status and return to normal libpq state */
 4441 rhaas@postgresql.org     2259                 :CBC        3478 :     res = PQgetResult(conn);
 4450                          2260         [ -  + ]:           3478 :     if (PQresultStatus(res) != PGRES_COMMAND_OK)
                               2261                 :                :     {
 1840 peter@eisentraut.org     2262                 :UBC           0 :         pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname);
  737 tgl@sss.pgh.pa.us        2263                 :              0 :         pg_log_error_detail("Error message from server: %s", PQerrorMessage(conn));
                               2264                 :              0 :         pg_log_error_detail("Command was: %s", q->data);
 4441 rhaas@postgresql.org     2265                 :              0 :         exit_nicely(1);
                               2266                 :                :     }
 7957 bruce@momjian.us         2267                 :CBC        3478 :     PQclear(res);
                               2268                 :                : 
                               2269                 :                :     /* Do this to ensure we've pumped libpq back to idle state */
 2873 tgl@sss.pgh.pa.us        2270         [ -  + ]:           3478 :     if (PQgetResult(conn) != NULL)
 1840 peter@eisentraut.org     2271                 :UBC           0 :         pg_log_warning("unexpected extra results during COPY of table \"%s\"",
                               2272                 :                :                        classname);
                               2273                 :                : 
 8010 tgl@sss.pgh.pa.us        2274                 :CBC        3478 :     destroyPQExpBuffer(q);
                               2275                 :           3478 :     return 1;
                               2276                 :                : }
                               2277                 :                : 
                               2278                 :                : /*
                               2279                 :                :  * Dump table data using INSERT commands.
                               2280                 :                :  *
                               2281                 :                :  * Caution: when we restore from an archive file direct to database, the
                               2282                 :                :  * INSERT commands emitted by this function have to be parsed by
                               2283                 :                :  * pg_backup_db.c's ExecuteSimpleCommands(), which will not handle comments,
                               2284                 :                :  * E'' strings, or dollar-quoted strings.  So don't emit anything like that.
                               2285                 :                :  */
                               2286                 :                : static int
 1159 peter@eisentraut.org     2287                 :             69 : dumpTableData_insert(Archive *fout, const void *dcontext)
                               2288                 :                : {
 7435 tgl@sss.pgh.pa.us        2289                 :             69 :     TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
                               2290                 :             69 :     TableInfo  *tbinfo = tdinfo->tdtable;
 3014                          2291                 :             69 :     DumpOptions *dopt = fout->dopt;
 8010                          2292                 :             69 :     PQExpBuffer q = createPQExpBuffer();
 3803                          2293                 :             69 :     PQExpBuffer insertStmt = NULL;
                               2294                 :                :     char       *attgenerated;
                               2295                 :                :     PGresult   *res;
                               2296                 :                :     int         nfields,
                               2297                 :                :                 i;
 1865 alvherre@alvh.no-ip.     2298                 :             69 :     int         rows_per_statement = dopt->dump_inserts;
                               2299                 :             69 :     int         rows_this_statement = 0;
                               2300                 :                : 
                               2301                 :                :     /*
                               2302                 :                :      * If we're going to emit INSERTs with column names, the most efficient
                               2303                 :                :      * way to deal with generated columns is to exclude them entirely.  For
                               2304                 :                :      * INSERTs without column names, we have to emit DEFAULT rather than the
                               2305                 :                :      * actual column value --- but we can save a few cycles by fetching nulls
                               2306                 :                :      * rather than the uninteresting-to-us value.
                               2307                 :                :      */
  874 tgl@sss.pgh.pa.us        2308                 :             69 :     attgenerated = (char *) pg_malloc(tbinfo->numatts * sizeof(char));
                               2309                 :             69 :     appendPQExpBufferStr(q, "DECLARE _pg_dump_cursor CURSOR FOR SELECT ");
                               2310                 :             69 :     nfields = 0;
                               2311         [ +  + ]:            221 :     for (i = 0; i < tbinfo->numatts; i++)
                               2312                 :                :     {
                               2313         [ +  + ]:            152 :         if (tbinfo->attisdropped[i])
                               2314                 :              2 :             continue;
                               2315   [ +  +  +  + ]:            150 :         if (tbinfo->attgenerated[i] && dopt->column_inserts)
                               2316                 :              5 :             continue;
                               2317         [ +  + ]:            145 :         if (nfields > 0)
                               2318                 :             83 :             appendPQExpBufferStr(q, ", ");
                               2319         [ +  + ]:            145 :         if (tbinfo->attgenerated[i])
                               2320                 :              5 :             appendPQExpBufferStr(q, "NULL");
                               2321                 :                :         else
                               2322                 :            140 :             appendPQExpBufferStr(q, fmtId(tbinfo->attnames[i]));
                               2323                 :            145 :         attgenerated[nfields] = tbinfo->attgenerated[i];
                               2324                 :            145 :         nfields++;
                               2325                 :                :     }
                               2326                 :                :     /* Servers before 9.4 will complain about zero-column SELECT */
                               2327         [ +  + ]:             69 :     if (nfields == 0)
                               2328                 :              7 :         appendPQExpBufferStr(q, "NULL");
                               2329                 :             69 :     appendPQExpBuffer(q, " FROM ONLY %s",
 2239                          2330                 :             69 :                       fmtQualifiedDumpable(tbinfo));
 4814                          2331         [ -  + ]:             69 :     if (tdinfo->filtercond)
 4814 tgl@sss.pgh.pa.us        2332                 :UBC           0 :         appendPQExpBuffer(q, " %s", tdinfo->filtercond);
                               2333                 :                : 
 4450 rhaas@postgresql.org     2334                 :CBC          69 :     ExecuteSqlStatement(fout, q->data);
                               2335                 :                : 
                               2336                 :                :     while (1)
                               2337                 :                :     {
                               2338                 :            119 :         res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
                               2339                 :                :                               PGRES_TUPLES_OK);
                               2340                 :                : 
                               2341                 :                :         /* cross-check field count, allowing for dummy NULL if any */
  874 tgl@sss.pgh.pa.us        2342   [ +  +  +  - ]:            119 :         if (nfields != PQnfields(res) &&
                               2343         [ -  + ]:             10 :             !(nfields == 0 && PQnfields(res) == 1))
  737 tgl@sss.pgh.pa.us        2344                 :UBC           0 :             pg_fatal("wrong number of fields retrieved from table \"%s\"",
                               2345                 :                :                      tbinfo->dobj.name);
                               2346                 :                : 
                               2347                 :                :         /*
                               2348                 :                :          * First time through, we build as much of the INSERT statement as
                               2349                 :                :          * possible in "insertStmt", which we can then just print for each
                               2350                 :                :          * statement. If the table happens to have zero dumpable columns then
                               2351                 :                :          * this will be a complete statement, otherwise it will end in
                               2352                 :                :          * "VALUES" and be ready to have the row's column values printed.
                               2353                 :                :          */
 1865 alvherre@alvh.no-ip.     2354         [ +  + ]:CBC         119 :         if (insertStmt == NULL)
                               2355                 :                :         {
                               2356                 :                :             TableInfo  *targettab;
                               2357                 :                : 
                               2358                 :             69 :             insertStmt = createPQExpBuffer();
                               2359                 :                : 
                               2360                 :                :             /*
                               2361                 :                :              * When load-via-partition-root is set or forced, get the root
                               2362                 :                :              * table name for the partition table, so that we can reload data
                               2363                 :                :              * through the root table.
                               2364                 :                :              */
  394 tgl@sss.pgh.pa.us        2365         [ +  + ]:             69 :             if (tbinfo->ispartition &&
                               2366   [ +  -  +  + ]:             40 :                 (dopt->load_via_partition_root ||
                               2367                 :             20 :                  forcePartitionRootLoad(tbinfo)))
 1865 alvherre@alvh.no-ip.     2368                 :              3 :                 targettab = getRootTableInfo(tbinfo);
                               2369                 :                :             else
                               2370                 :             66 :                 targettab = tbinfo;
                               2371                 :                : 
                               2372                 :             69 :             appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
                               2373                 :             69 :                               fmtQualifiedDumpable(targettab));
                               2374                 :                : 
                               2375                 :                :             /* corner case for zero-column table */
                               2376         [ +  + ]:             69 :             if (nfields == 0)
                               2377                 :                :             {
                               2378                 :              7 :                 appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
                               2379                 :                :             }
                               2380                 :                :             else
                               2381                 :                :             {
                               2382                 :                :                 /* append the list of column names if required */
                               2383         [ +  + ]:             62 :                 if (dopt->column_inserts)
                               2384                 :                :                 {
                               2385                 :             27 :                     appendPQExpBufferChar(insertStmt, '(');
                               2386         [ +  + ]:             88 :                     for (int field = 0; field < nfields; field++)
                               2387                 :                :                     {
                               2388         [ +  + ]:             61 :                         if (field > 0)
                               2389                 :             34 :                             appendPQExpBufferStr(insertStmt, ", ");
                               2390                 :             61 :                         appendPQExpBufferStr(insertStmt,
                               2391                 :             61 :                                              fmtId(PQfname(res, field)));
                               2392                 :                :                     }
                               2393                 :             27 :                     appendPQExpBufferStr(insertStmt, ") ");
                               2394                 :                :                 }
                               2395                 :                : 
                               2396         [ +  + ]:             62 :                 if (tbinfo->needs_override)
                               2397                 :              2 :                     appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE ");
                               2398                 :                : 
                               2399                 :             62 :                 appendPQExpBufferStr(insertStmt, "VALUES");
                               2400                 :                :             }
                               2401                 :                :         }
                               2402                 :                : 
                               2403         [ +  + ]:           3190 :         for (int tuple = 0; tuple < PQntuples(res); tuple++)
                               2404                 :                :         {
                               2405                 :                :             /* Write the INSERT if not in the middle of a multi-row INSERT. */
                               2406         [ +  + ]:           3071 :             if (rows_this_statement == 0)
                               2407                 :           3065 :                 archputs(insertStmt->data, fout);
                               2408                 :                : 
                               2409                 :                :             /*
                               2410                 :                :              * If it is zero-column table then we've already written the
                               2411                 :                :              * complete statement, which will mean we've disobeyed
                               2412                 :                :              * --rows-per-insert when it's set greater than 1.  We do support
                               2413                 :                :              * a way to make this multi-row with: SELECT UNION ALL SELECT
                               2414                 :                :              * UNION ALL ... but that's non-standard so we should avoid it
                               2415                 :                :              * given that using INSERTs is mostly only ever needed for
                               2416                 :                :              * cross-database exports.
                               2417                 :                :              */
 3803 tgl@sss.pgh.pa.us        2418         [ +  + ]:           3071 :             if (nfields == 0)
                               2419                 :              6 :                 continue;
                               2420                 :                : 
                               2421                 :                :             /* Emit a row heading */
 1865 alvherre@alvh.no-ip.     2422         [ +  + ]:           3065 :             if (rows_per_statement == 1)
                               2423                 :           3056 :                 archputs(" (", fout);
                               2424         [ +  + ]:              9 :             else if (rows_this_statement > 0)
                               2425                 :              6 :                 archputs(",\n\t(", fout);
                               2426                 :                :             else
                               2427                 :              3 :                 archputs("\n\t(", fout);
                               2428                 :                : 
                               2429         [ +  + ]:           9249 :             for (int field = 0; field < nfields; field++)
                               2430                 :                :             {
 8010 tgl@sss.pgh.pa.us        2431         [ +  + ]:           6184 :                 if (field > 0)
 3803                          2432                 :           3119 :                     archputs(", ", fout);
  874                          2433         [ +  + ]:           6184 :                 if (attgenerated[field])
                               2434                 :                :                 {
 1842 peter@eisentraut.org     2435                 :              2 :                     archputs("DEFAULT", fout);
                               2436                 :              2 :                     continue;
                               2437                 :                :                 }
 8010 tgl@sss.pgh.pa.us        2438         [ +  + ]:           6182 :                 if (PQgetisnull(res, tuple, field))
                               2439                 :                :                 {
 3803                          2440                 :             83 :                     archputs("NULL", fout);
 8010                          2441                 :             83 :                     continue;
                               2442                 :                :                 }
                               2443                 :                : 
                               2444                 :                :                 /* XXX This code is partially duplicated in ruleutils.c */
                               2445   [ +  +  +  + ]:           6099 :                 switch (PQftype(res, field))
                               2446                 :                :                 {
                               2447                 :           4069 :                     case INT2OID:
                               2448                 :                :                     case INT4OID:
                               2449                 :                :                     case INT8OID:
                               2450                 :                :                     case OIDOID:
                               2451                 :                :                     case FLOAT4OID:
                               2452                 :                :                     case FLOAT8OID:
                               2453                 :                :                     case NUMERICOID:
                               2454                 :                :                         {
                               2455                 :                :                             /*
                               2456                 :                :                              * These types are printed without quotes unless
                               2457                 :                :                              * they contain values that aren't accepted by the
                               2458                 :                :                              * scanner unquoted (e.g., 'NaN').  Note that
                               2459                 :                :                              * strtod() and friends might accept NaN, so we
                               2460                 :                :                              * can't use that to test.
                               2461                 :                :                              *
                               2462                 :                :                              * In reality we only need to defend against
                               2463                 :                :                              * infinity and NaN, so we need not get too crazy
                               2464                 :                :                              * about pattern matching here.
                               2465                 :                :                              */
 7893 bruce@momjian.us         2466                 :           4069 :                             const char *s = PQgetvalue(res, tuple, field);
                               2467                 :                : 
                               2468         [ +  + ]:           4069 :                             if (strspn(s, "0123456789 +-eE.") == strlen(s))
 3803 tgl@sss.pgh.pa.us        2469                 :           4067 :                                 archputs(s, fout);
                               2470                 :                :                             else
 7893 bruce@momjian.us         2471                 :              2 :                                 archprintf(fout, "'%s'", s);
                               2472                 :                :                         }
                               2473                 :           4069 :                         break;
                               2474                 :                : 
 8010 tgl@sss.pgh.pa.us        2475                 :              2 :                     case BITOID:
                               2476                 :                :                     case VARBITOID:
                               2477                 :              2 :                         archprintf(fout, "B'%s'",
                               2478                 :                :                                    PQgetvalue(res, tuple, field));
                               2479                 :              2 :                         break;
                               2480                 :                : 
 7910 peter_e@gmx.net          2481                 :              4 :                     case BOOLOID:
 7893 bruce@momjian.us         2482         [ +  + ]:              4 :                         if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
 3803 tgl@sss.pgh.pa.us        2483                 :              2 :                             archputs("true", fout);
                               2484                 :                :                         else
                               2485                 :              2 :                             archputs("false", fout);
 7910 peter_e@gmx.net          2486                 :              4 :                         break;
                               2487                 :                : 
                               2488                 :           2024 :                     default:
                               2489                 :                :                         /* All other types are printed as string literals. */
 8010 tgl@sss.pgh.pa.us        2490                 :           2024 :                         resetPQExpBuffer(q);
 6531                          2491                 :           2024 :                         appendStringLiteralAH(q,
                               2492                 :                :                                               PQgetvalue(res, tuple, field),
                               2493                 :                :                                               fout);
 7018                          2494                 :           2024 :                         archputs(q->data, fout);
 8010                          2495                 :           2024 :                         break;
                               2496                 :                :                 }
                               2497                 :                :             }
                               2498                 :                : 
                               2499                 :                :             /* Terminate the row ... */
 1865 alvherre@alvh.no-ip.     2500                 :           3065 :             archputs(")", fout);
                               2501                 :                : 
                               2502                 :                :             /* ... and the statement, if the target no. of rows is reached */
                               2503         [ +  + ]:           3065 :             if (++rows_this_statement >= rows_per_statement)
                               2504                 :                :             {
                               2505         [ -  + ]:           3058 :                 if (dopt->do_nothing)
 1865 alvherre@alvh.no-ip.     2506                 :UBC           0 :                     archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2507                 :                :                 else
 1865 alvherre@alvh.no-ip.     2508                 :CBC        3058 :                     archputs(";\n", fout);
                               2509                 :                :                 /* Reset the row counter */
                               2510                 :           3058 :                 rows_this_statement = 0;
                               2511                 :                :             }
                               2512                 :                :         }
                               2513                 :                : 
 4450 rhaas@postgresql.org     2514         [ +  + ]:            119 :         if (PQntuples(res) <= 0)
                               2515                 :                :         {
                               2516                 :             69 :             PQclear(res);
                               2517                 :             69 :             break;
                               2518                 :                :         }
                               2519                 :             50 :         PQclear(res);
                               2520                 :                :     }
                               2521                 :                : 
                               2522                 :                :     /* Terminate any statements that didn't make the row count. */
 1865 alvherre@alvh.no-ip.     2523         [ +  + ]:             69 :     if (rows_this_statement > 0)
                               2524                 :                :     {
                               2525         [ -  + ]:              1 :         if (dopt->do_nothing)
 1865 alvherre@alvh.no-ip.     2526                 :UBC           0 :             archputs(" ON CONFLICT DO NOTHING;\n", fout);
                               2527                 :                :         else
 1865 alvherre@alvh.no-ip.     2528                 :CBC           1 :             archputs(";\n", fout);
                               2529                 :                :     }
                               2530                 :                : 
 3803 tgl@sss.pgh.pa.us        2531                 :             69 :     archputs("\n\n", fout);
                               2532                 :                : 
 4450 rhaas@postgresql.org     2533                 :             69 :     ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
                               2534                 :                : 
 8010 tgl@sss.pgh.pa.us        2535                 :             69 :     destroyPQExpBuffer(q);
 3803                          2536         [ +  - ]:             69 :     if (insertStmt != NULL)
                               2537                 :             69 :         destroyPQExpBuffer(insertStmt);
  874                          2538                 :             69 :     free(attgenerated);
                               2539                 :                : 
 8010                          2540                 :             69 :     return 1;
                               2541                 :                : }
                               2542                 :                : 
                               2543                 :                : /*
                               2544                 :                :  * getRootTableInfo:
                               2545                 :                :  *     get the root TableInfo for the given partition table.
                               2546                 :                :  */
                               2547                 :                : static TableInfo *
 1159 peter@eisentraut.org     2548                 :              9 : getRootTableInfo(const TableInfo *tbinfo)
                               2549                 :                : {
                               2550                 :                :     TableInfo  *parentTbinfo;
                               2551                 :                : 
 2435 rhaas@postgresql.org     2552         [ -  + ]:              9 :     Assert(tbinfo->ispartition);
                               2553         [ -  + ]:              9 :     Assert(tbinfo->numParents == 1);
                               2554                 :                : 
                               2555                 :              9 :     parentTbinfo = tbinfo->parents[0];
                               2556         [ -  + ]:              9 :     while (parentTbinfo->ispartition)
                               2557                 :                :     {
 2435 rhaas@postgresql.org     2558         [ #  # ]:UBC           0 :         Assert(parentTbinfo->numParents == 1);
                               2559                 :              0 :         parentTbinfo = parentTbinfo->parents[0];
                               2560                 :                :     }
                               2561                 :                : 
 2435 rhaas@postgresql.org     2562                 :CBC           9 :     return parentTbinfo;
                               2563                 :                : }
                               2564                 :                : 
                               2565                 :                : /*
                               2566                 :                :  * forcePartitionRootLoad
                               2567                 :                :  *     Check if we must force load_via_partition_root for this partition.
                               2568                 :                :  *
                               2569                 :                :  * This is required if any level of ancestral partitioned table has an
                               2570                 :                :  * unsafe partitioning scheme.
                               2571                 :                :  */
                               2572                 :                : static bool
  394 tgl@sss.pgh.pa.us        2573                 :            955 : forcePartitionRootLoad(const TableInfo *tbinfo)
                               2574                 :                : {
                               2575                 :                :     TableInfo  *parentTbinfo;
                               2576                 :                : 
                               2577         [ -  + ]:            955 :     Assert(tbinfo->ispartition);
                               2578         [ -  + ]:            955 :     Assert(tbinfo->numParents == 1);
                               2579                 :                : 
                               2580                 :            955 :     parentTbinfo = tbinfo->parents[0];
                               2581         [ +  + ]:            955 :     if (parentTbinfo->unsafe_partitions)
                               2582                 :              9 :         return true;
                               2583         [ +  + ]:           1162 :     while (parentTbinfo->ispartition)
                               2584                 :                :     {
                               2585         [ -  + ]:            216 :         Assert(parentTbinfo->numParents == 1);
                               2586                 :            216 :         parentTbinfo = parentTbinfo->parents[0];
                               2587         [ -  + ]:            216 :         if (parentTbinfo->unsafe_partitions)
  394 tgl@sss.pgh.pa.us        2588                 :UBC           0 :             return true;
                               2589                 :                :     }
                               2590                 :                : 
  394 tgl@sss.pgh.pa.us        2591                 :CBC         946 :     return false;
                               2592                 :                : }
                               2593                 :                : 
                               2594                 :                : /*
                               2595                 :                :  * dumpTableData -
                               2596                 :                :  *    dump the contents of a single table
                               2597                 :                :  *
                               2598                 :                :  * Actually, this just makes an ArchiveEntry for the table contents.
                               2599                 :                :  */
                               2600                 :                : static void
 1159 peter@eisentraut.org     2601                 :           3616 : dumpTableData(Archive *fout, const TableDataInfo *tdinfo)
                               2602                 :                : {
 3014 tgl@sss.pgh.pa.us        2603                 :           3616 :     DumpOptions *dopt = fout->dopt;
 7435                          2604                 :           3616 :     TableInfo  *tbinfo = tdinfo->tdtable;
 4813                          2605                 :           3616 :     PQExpBuffer copyBuf = createPQExpBuffer();
 4039 andrew@dunslane.net      2606                 :           3616 :     PQExpBuffer clistBuf = createPQExpBuffer();
                               2607                 :                :     DataDumperPtr dumpFn;
  394 tgl@sss.pgh.pa.us        2608                 :           3616 :     char       *tdDefn = NULL;
                               2609                 :                :     char       *copyStmt;
                               2610                 :                :     const char *copyFrom;
                               2611                 :                : 
                               2612                 :                :     /* We had better have loaded per-column details about this table */
 1285                          2613         [ -  + ]:           3616 :     Assert(tbinfo->interesting);
                               2614                 :                : 
                               2615                 :                :     /*
                               2616                 :                :      * When load-via-partition-root is set or forced, get the root table name
                               2617                 :                :      * for the partition table, so that we can reload data through the root
                               2618                 :                :      * table.  Then construct a comment to be inserted into the TOC entry's
                               2619                 :                :      * defn field, so that such cases can be identified reliably.
                               2620                 :                :      */
  394                          2621         [ +  + ]:           3616 :     if (tbinfo->ispartition &&
                               2622   [ +  -  +  + ]:           1870 :         (dopt->load_via_partition_root ||
                               2623                 :            935 :          forcePartitionRootLoad(tbinfo)))
                               2624                 :              6 :     {
                               2625                 :                :         TableInfo  *parentTbinfo;
                               2626                 :                : 
                               2627                 :              6 :         parentTbinfo = getRootTableInfo(tbinfo);
                               2628                 :              6 :         copyFrom = fmtQualifiedDumpable(parentTbinfo);
                               2629                 :              6 :         printfPQExpBuffer(copyBuf, "-- load via partition root %s",
                               2630                 :                :                           copyFrom);
                               2631                 :              6 :         tdDefn = pg_strdup(copyBuf->data);
                               2632                 :                :     }
                               2633                 :                :     else
                               2634                 :           3610 :         copyFrom = fmtQualifiedDumpable(tbinfo);
                               2635                 :                : 
 1376 alvherre@alvh.no-ip.     2636         [ +  + ]:           3616 :     if (dopt->dump_inserts == 0)
                               2637                 :                :     {
                               2638                 :                :         /* Dump/restore using COPY */
 7435 tgl@sss.pgh.pa.us        2639                 :           3547 :         dumpFn = dumpTableData_copy;
                               2640                 :                :         /* must use 2 steps here 'cause fmtId is nonreentrant */
  394                          2641                 :           3547 :         printfPQExpBuffer(copyBuf, "COPY %s ",
                               2642                 :                :                           copyFrom);
 1972 andres@anarazel.de       2643                 :           3547 :         appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
                               2644                 :                :                           fmtCopyColumnList(tbinfo, clistBuf));
 7435 tgl@sss.pgh.pa.us        2645                 :           3547 :         copyStmt = copyBuf->data;
                               2646                 :                :     }
                               2647                 :                :     else
                               2648                 :                :     {
                               2649                 :                :         /* Restore using INSERT */
                               2650                 :             69 :         dumpFn = dumpTableData_insert;
                               2651                 :             69 :         copyStmt = NULL;
                               2652                 :                :     }
                               2653                 :                : 
                               2654                 :                :     /*
                               2655                 :                :      * Note: although the TableDataInfo is a full DumpableObject, we treat its
                               2656                 :                :      * dependency on its table as "special" and pass it to ArchiveEntry now.
                               2657                 :                :      * See comments for BuildArchiveDependencies.
                               2658                 :                :      */
 2930 sfrost@snowman.net       2659         [ +  - ]:           3616 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2660                 :                :     {
                               2661                 :                :         TocEntry   *te;
                               2662                 :                : 
 2039 tgl@sss.pgh.pa.us        2663                 :           3616 :         te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.     2664                 :           3616 :                           ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2665                 :                :                                        .namespace = tbinfo->dobj.namespace->dobj.name,
                               2666                 :                :                                        .owner = tbinfo->rolname,
                               2667                 :                :                                        .description = "TABLE DATA",
                               2668                 :                :                                        .section = SECTION_DATA,
                               2669                 :                :                                        .createStmt = tdDefn,
                               2670                 :                :                                        .copyStmt = copyStmt,
                               2671                 :                :                                        .deps = &(tbinfo->dobj.dumpId),
                               2672                 :                :                                        .nDeps = 1,
                               2673                 :                :                                        .dumpFn = dumpFn,
                               2674                 :                :                                        .dumpArg = tdinfo));
                               2675                 :                : 
                               2676                 :                :         /*
                               2677                 :                :          * Set the TocEntry's dataLength in case we are doing a parallel dump
                               2678                 :                :          * and want to order dump jobs by table size.  We choose to measure
                               2679                 :                :          * dataLength in table pages (including TOAST pages) during dump, so
                               2680                 :                :          * no scaling is needed.
                               2681                 :                :          *
                               2682                 :                :          * However, relpages is declared as "integer" in pg_class, and hence
                               2683                 :                :          * also in TableInfo, but it's really BlockNumber a/k/a unsigned int.
                               2684                 :                :          * Cast so that we get the right interpretation of table sizes
                               2685                 :                :          * exceeding INT_MAX pages.
                               2686                 :                :          */
 2039 tgl@sss.pgh.pa.us        2687                 :           3616 :         te->dataLength = (BlockNumber) tbinfo->relpages;
  860                          2688                 :           3616 :         te->dataLength += (BlockNumber) tbinfo->toastpages;
                               2689                 :                : 
                               2690                 :                :         /*
                               2691                 :                :          * If pgoff_t is only 32 bits wide, the above refinement is useless,
                               2692                 :                :          * and instead we'd better worry about integer overflow.  Clamp to
                               2693                 :                :          * INT_MAX if the correct result exceeds that.
                               2694                 :                :          */
                               2695                 :                :         if (sizeof(te->dataLength) == 4 &&
                               2696                 :                :             (tbinfo->relpages < 0 || tbinfo->toastpages < 0 ||
                               2697                 :                :              te->dataLength < 0))
                               2698                 :                :             te->dataLength = INT_MAX;
                               2699                 :                :     }
                               2700                 :                : 
 7435                          2701                 :           3616 :     destroyPQExpBuffer(copyBuf);
 4039 andrew@dunslane.net      2702                 :           3616 :     destroyPQExpBuffer(clistBuf);
 7435 tgl@sss.pgh.pa.us        2703                 :           3616 : }
                               2704                 :                : 
                               2705                 :                : /*
                               2706                 :                :  * refreshMatViewData -
                               2707                 :                :  *    load or refresh the contents of a single materialized view
                               2708                 :                :  *
                               2709                 :                :  * Actually, this just makes an ArchiveEntry for the REFRESH MATERIALIZED VIEW
                               2710                 :                :  * statement.
                               2711                 :                :  */
                               2712                 :                : static void
 1159 peter@eisentraut.org     2713                 :            365 : refreshMatViewData(Archive *fout, const TableDataInfo *tdinfo)
                               2714                 :                : {
 4060 kgrittn@postgresql.o     2715                 :            365 :     TableInfo  *tbinfo = tdinfo->tdtable;
                               2716                 :                :     PQExpBuffer q;
                               2717                 :                : 
                               2718                 :                :     /* If the materialized view is not flagged as populated, skip this. */
 3996 tgl@sss.pgh.pa.us        2719         [ +  + ]:            365 :     if (!tbinfo->relispopulated)
 4060 kgrittn@postgresql.o     2720                 :             74 :         return;
                               2721                 :                : 
                               2722                 :            291 :     q = createPQExpBuffer();
                               2723                 :                : 
                               2724                 :            291 :     appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
 2239 tgl@sss.pgh.pa.us        2725                 :            291 :                       fmtQualifiedDumpable(tbinfo));
                               2726                 :                : 
 2930 sfrost@snowman.net       2727         [ +  - ]:            291 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
                               2728                 :            291 :         ArchiveEntry(fout,
                               2729                 :                :                      tdinfo->dobj.catId, /* catalog ID */
 2489 tgl@sss.pgh.pa.us        2730                 :            291 :                      tdinfo->dobj.dumpId,    /* dump ID */
 1899 alvherre@alvh.no-ip.     2731                 :            291 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                               2732                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               2733                 :                :                                   .owner = tbinfo->rolname,
                               2734                 :                :                                   .description = "MATERIALIZED VIEW DATA",
                               2735                 :                :                                   .section = SECTION_POST_DATA,
                               2736                 :                :                                   .createStmt = q->data,
                               2737                 :                :                                   .deps = tdinfo->dobj.dependencies,
                               2738                 :                :                                   .nDeps = tdinfo->dobj.nDeps));
                               2739                 :                : 
 4060 kgrittn@postgresql.o     2740                 :            291 :     destroyPQExpBuffer(q);
                               2741                 :                : }
                               2742                 :                : 
                               2743                 :                : /*
                               2744                 :                :  * getTableData -
                               2745                 :                :  *    set up dumpable objects representing the contents of tables
                               2746                 :                :  */
                               2747                 :                : static void
 1972 andres@anarazel.de       2748                 :            153 : getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind)
                               2749                 :                : {
                               2750                 :                :     int         i;
                               2751                 :                : 
 8010 tgl@sss.pgh.pa.us        2752         [ +  + ]:          38935 :     for (i = 0; i < numTables; i++)
                               2753                 :                :     {
 2791 peter_e@gmx.net          2754   [ +  +  +  + ]:          38782 :         if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA &&
                               2755         [ +  + ]:            818 :             (!relkind || tblinfo[i].relkind == relkind))
 1972 andres@anarazel.de       2756                 :           5128 :             makeTableDataInfo(dopt, &(tblinfo[i]));
                               2757                 :                :     }
 4814 tgl@sss.pgh.pa.us        2758                 :            153 : }
                               2759                 :                : 
                               2760                 :                : /*
                               2761                 :                :  * Make a dumpable object for the data of this specific table
                               2762                 :                :  *
                               2763                 :                :  * Note: we make a TableDataInfo if and only if we are going to dump the
                               2764                 :                :  * table data; the "dump" field in such objects isn't very interesting.
                               2765                 :                :  */
                               2766                 :                : static void
 1972 andres@anarazel.de       2767                 :           5167 : makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo)
                               2768                 :                : {
                               2769                 :                :     TableDataInfo *tdinfo;
                               2770                 :                : 
                               2771                 :                :     /*
                               2772                 :                :      * Nothing to do if we already decided to dump the table.  This will
                               2773                 :                :      * happen for "config" tables.
                               2774                 :                :      */
 4449 tgl@sss.pgh.pa.us        2775         [ +  + ]:           5167 :     if (tbinfo->dataObj != NULL)
                               2776                 :              1 :         return;
                               2777                 :                : 
                               2778                 :                :     /* Skip VIEWs (no data to dump) */
                               2779         [ +  + ]:           5166 :     if (tbinfo->relkind == RELKIND_VIEW)
                               2780                 :            303 :         return;
                               2781                 :                :     /* Skip FOREIGN TABLEs (no data to dump) unless requested explicitly */
 1481 alvherre@alvh.no-ip.     2782         [ +  + ]:           4863 :     if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                               2783         [ +  + ]:             41 :         (foreign_servers_include_oids.head == NULL ||
 1431 tgl@sss.pgh.pa.us        2784         [ +  + ]:              4 :          !simple_oid_list_member(&foreign_servers_include_oids,
                               2785                 :                :                                  tbinfo->foreign_server)))
 4449                          2786                 :             40 :         return;
                               2787                 :                :     /* Skip partitioned tables (data in partitions) */
 2685 rhaas@postgresql.org     2788         [ +  + ]:           4823 :     if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
                               2789                 :            435 :         return;
                               2790                 :                : 
                               2791                 :                :     /* Don't dump data in unlogged tables, if so requested */
 4449 tgl@sss.pgh.pa.us        2792         [ +  + ]:           4388 :     if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
 3470 alvherre@alvh.no-ip.     2793         [ +  + ]:             32 :         dopt->no_unlogged_table_data)
 4449 tgl@sss.pgh.pa.us        2794                 :             14 :         return;
                               2795                 :                : 
                               2796                 :                :     /* Check that the data is not explicitly excluded */
                               2797         [ +  + ]:           4374 :     if (simple_oid_list_member(&tabledata_exclude_oids,
                               2798                 :                :                                tbinfo->dobj.catId.oid))
                               2799                 :              8 :         return;
                               2800                 :                : 
                               2801                 :                :     /* OK, let's dump it */
 4524 bruce@momjian.us         2802                 :           4366 :     tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
                               2803                 :                : 
 4060 kgrittn@postgresql.o     2804         [ +  + ]:           4366 :     if (tbinfo->relkind == RELKIND_MATVIEW)
                               2805                 :            365 :         tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
 2791 peter_e@gmx.net          2806         [ +  + ]:           4001 :     else if (tbinfo->relkind == RELKIND_SEQUENCE)
                               2807                 :            385 :         tdinfo->dobj.objType = DO_SEQUENCE_SET;
                               2808                 :                :     else
 4060 kgrittn@postgresql.o     2809                 :           3616 :         tdinfo->dobj.objType = DO_TABLE_DATA;
                               2810                 :                : 
                               2811                 :                :     /*
                               2812                 :                :      * Note: use tableoid 0 so that this object won't be mistaken for
                               2813                 :                :      * something that pg_depend entries apply to.
                               2814                 :                :      */
 4814 tgl@sss.pgh.pa.us        2815                 :           4366 :     tdinfo->dobj.catId.tableoid = 0;
                               2816                 :           4366 :     tdinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               2817                 :           4366 :     AssignDumpId(&tdinfo->dobj);
                               2818                 :           4366 :     tdinfo->dobj.name = tbinfo->dobj.name;
                               2819                 :           4366 :     tdinfo->dobj.namespace = tbinfo->dobj.namespace;
                               2820                 :           4366 :     tdinfo->tdtable = tbinfo;
 4753 bruce@momjian.us         2821                 :           4366 :     tdinfo->filtercond = NULL;   /* might get set later */
 4814 tgl@sss.pgh.pa.us        2822                 :           4366 :     addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId);
                               2823                 :                : 
                               2824                 :                :     /* A TableDataInfo contains data, of course */
  860                          2825                 :           4366 :     tdinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               2826                 :                : 
 4814                          2827                 :           4366 :     tbinfo->dataObj = tdinfo;
                               2828                 :                : 
                               2829                 :                :     /* Make sure that we'll collect per-column info for this table. */
 1285                          2830                 :           4366 :     tbinfo->interesting = true;
                               2831                 :                : }
                               2832                 :                : 
                               2833                 :                : /*
                               2834                 :                :  * The refresh for a materialized view must be dependent on the refresh for
                               2835                 :                :  * any materialized view that this one is dependent on.
                               2836                 :                :  *
                               2837                 :                :  * This must be called after all the objects are created, but before they are
                               2838                 :                :  * sorted.
                               2839                 :                :  */
                               2840                 :                : static void
 4060 kgrittn@postgresql.o     2841                 :            139 : buildMatViewRefreshDependencies(Archive *fout)
                               2842                 :                : {
                               2843                 :                :     PQExpBuffer query;
                               2844                 :                :     PGresult   *res;
                               2845                 :                :     int         ntups,
                               2846                 :                :                 i;
                               2847                 :                :     int         i_classid,
                               2848                 :                :                 i_objid,
                               2849                 :                :                 i_refobjid;
                               2850                 :                : 
                               2851                 :                :     /* No Mat Views before 9.3. */
 4050                          2852         [ -  + ]:            139 :     if (fout->remoteVersion < 90300)
 4050 kgrittn@postgresql.o     2853                 :UBC           0 :         return;
                               2854                 :                : 
 4050 kgrittn@postgresql.o     2855                 :CBC         139 :     query = createPQExpBuffer();
                               2856                 :                : 
 3800 heikki.linnakangas@i     2857                 :            139 :     appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
                               2858                 :                :                          "( "
                               2859                 :                :                          "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
                               2860                 :                :                          "FROM pg_depend d1 "
                               2861                 :                :                          "JOIN pg_class c1 ON c1.oid = d1.objid "
                               2862                 :                :                          "AND c1.relkind = " CppAsString2(RELKIND_MATVIEW)
                               2863                 :                :                          " JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
                               2864                 :                :                          "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
                               2865                 :                :                          "AND d2.objid = r1.oid "
                               2866                 :                :                          "AND d2.refobjid <> d1.objid "
                               2867                 :                :                          "JOIN pg_class c2 ON c2.oid = d2.refobjid "
                               2868                 :                :                          "AND c2.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               2869                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               2870                 :                :                          "WHERE d1.classid = 'pg_class'::regclass "
                               2871                 :                :                          "UNION "
                               2872                 :                :                          "SELECT w.objid, d3.refobjid, c3.relkind "
                               2873                 :                :                          "FROM w "
                               2874                 :                :                          "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
                               2875                 :                :                          "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
                               2876                 :                :                          "AND d3.objid = r3.oid "
                               2877                 :                :                          "AND d3.refobjid <> w.refobjid "
                               2878                 :                :                          "JOIN pg_class c3 ON c3.oid = d3.refobjid "
                               2879                 :                :                          "AND c3.relkind IN (" CppAsString2(RELKIND_MATVIEW) ","
                               2880                 :                :                          CppAsString2(RELKIND_VIEW) ") "
                               2881                 :                :                          ") "
                               2882                 :                :                          "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
                               2883                 :                :                          "FROM w "
                               2884                 :                :                          "WHERE refrelkind = " CppAsString2(RELKIND_MATVIEW));
                               2885                 :                : 
 4060 kgrittn@postgresql.o     2886                 :            139 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               2887                 :                : 
                               2888                 :            139 :     ntups = PQntuples(res);
                               2889                 :                : 
                               2890                 :            139 :     i_classid = PQfnumber(res, "classid");
                               2891                 :            139 :     i_objid = PQfnumber(res, "objid");
                               2892                 :            139 :     i_refobjid = PQfnumber(res, "refobjid");
                               2893                 :                : 
                               2894         [ +  + ]:            415 :     for (i = 0; i < ntups; i++)
                               2895                 :                :     {
                               2896                 :                :         CatalogId   objId;
                               2897                 :                :         CatalogId   refobjId;
                               2898                 :                :         DumpableObject *dobj;
                               2899                 :                :         DumpableObject *refdobj;
                               2900                 :                :         TableInfo  *tbinfo;
                               2901                 :                :         TableInfo  *reftbinfo;
                               2902                 :                : 
                               2903                 :            276 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                               2904                 :            276 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                               2905                 :            276 :         refobjId.tableoid = objId.tableoid;
                               2906                 :            276 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                               2907                 :                : 
                               2908                 :            276 :         dobj = findObjectByCatalogId(objId);
                               2909         [ -  + ]:            276 :         if (dobj == NULL)
 4060 kgrittn@postgresql.o     2910                 :UBC           0 :             continue;
                               2911                 :                : 
 4060 kgrittn@postgresql.o     2912         [ -  + ]:CBC         276 :         Assert(dobj->objType == DO_TABLE);
                               2913                 :            276 :         tbinfo = (TableInfo *) dobj;
                               2914         [ -  + ]:            276 :         Assert(tbinfo->relkind == RELKIND_MATVIEW);
                               2915                 :            276 :         dobj = (DumpableObject *) tbinfo->dataObj;
                               2916         [ +  + ]:            276 :         if (dobj == NULL)
                               2917                 :             42 :             continue;
                               2918         [ -  + ]:            234 :         Assert(dobj->objType == DO_REFRESH_MATVIEW);
                               2919                 :                : 
                               2920                 :            234 :         refdobj = findObjectByCatalogId(refobjId);
                               2921         [ -  + ]:            234 :         if (refdobj == NULL)
 4060 kgrittn@postgresql.o     2922                 :UBC           0 :             continue;
                               2923                 :                : 
 4060 kgrittn@postgresql.o     2924         [ -  + ]:CBC         234 :         Assert(refdobj->objType == DO_TABLE);
                               2925                 :            234 :         reftbinfo = (TableInfo *) refdobj;
                               2926         [ -  + ]:            234 :         Assert(reftbinfo->relkind == RELKIND_MATVIEW);
                               2927                 :            234 :         refdobj = (DumpableObject *) reftbinfo->dataObj;
                               2928         [ -  + ]:            234 :         if (refdobj == NULL)
 4060 kgrittn@postgresql.o     2929                 :UBC           0 :             continue;
 4060 kgrittn@postgresql.o     2930         [ -  + ]:CBC         234 :         Assert(refdobj->objType == DO_REFRESH_MATVIEW);
                               2931                 :                : 
                               2932                 :            234 :         addObjectDependency(dobj, refdobj->dumpId);
                               2933                 :                : 
 3996 tgl@sss.pgh.pa.us        2934         [ +  + ]:            234 :         if (!reftbinfo->relispopulated)
                               2935                 :             37 :             tbinfo->relispopulated = false;
                               2936                 :                :     }
                               2937                 :                : 
 4060 kgrittn@postgresql.o     2938                 :            139 :     PQclear(res);
                               2939                 :                : 
                               2940                 :            139 :     destroyPQExpBuffer(query);
                               2941                 :                : }
                               2942                 :                : 
                               2943                 :                : /*
                               2944                 :                :  * getTableDataFKConstraints -
                               2945                 :                :  *    add dump-order dependencies reflecting foreign key constraints
                               2946                 :                :  *
                               2947                 :                :  * This code is executed only in a data-only dump --- in schema+data dumps
                               2948                 :                :  * we handle foreign key issues by not creating the FK constraints until
                               2949                 :                :  * after the data is loaded.  In a data-only dump, however, we want to
                               2950                 :                :  * order the table data objects in such a way that a table's referenced
                               2951                 :                :  * tables are restored first.  (In the presence of circular references or
                               2952                 :                :  * self-references this may be impossible; we'll detect and complain about
                               2953                 :                :  * that during the dependency sorting step.)
                               2954                 :                :  */
                               2955                 :                : static void
 5697 tgl@sss.pgh.pa.us        2956                 :              6 : getTableDataFKConstraints(void)
                               2957                 :                : {
                               2958                 :                :     DumpableObject **dobjs;
                               2959                 :                :     int         numObjs;
                               2960                 :                :     int         i;
                               2961                 :                : 
                               2962                 :                :     /* Search through all the dumpable objects for FK constraints */
                               2963                 :              6 :     getDumpableObjects(&dobjs, &numObjs);
                               2964         [ +  + ]:          25399 :     for (i = 0; i < numObjs; i++)
                               2965                 :                :     {
                               2966         [ +  + ]:          25393 :         if (dobjs[i]->objType == DO_FK_CONSTRAINT)
                               2967                 :                :         {
                               2968                 :              6 :             ConstraintInfo *cinfo = (ConstraintInfo *) dobjs[i];
                               2969                 :                :             TableInfo  *ftable;
                               2970                 :                : 
                               2971                 :                :             /* Not interesting unless both tables are to be dumped */
                               2972         [ +  - ]:              6 :             if (cinfo->contable == NULL ||
                               2973         [ +  + ]:              6 :                 cinfo->contable->dataObj == NULL)
                               2974                 :              3 :                 continue;
                               2975                 :              3 :             ftable = findTableByOid(cinfo->confrelid);
                               2976         [ +  - ]:              3 :             if (ftable == NULL ||
                               2977         [ -  + ]:              3 :                 ftable->dataObj == NULL)
 5697 tgl@sss.pgh.pa.us        2978                 :UBC           0 :                 continue;
                               2979                 :                : 
                               2980                 :                :             /*
                               2981                 :                :              * Okay, make referencing table's TABLE_DATA object depend on the
                               2982                 :                :              * referenced table's TABLE_DATA object.
                               2983                 :                :              */
 5697 tgl@sss.pgh.pa.us        2984                 :CBC           3 :             addObjectDependency(&cinfo->contable->dataObj->dobj,
                               2985                 :              3 :                                 ftable->dataObj->dobj.dumpId);
                               2986                 :                :         }
                               2987                 :                :     }
                               2988                 :              6 :     free(dobjs);
                               2989                 :              6 : }
                               2990                 :                : 
                               2991                 :                : 
                               2992                 :                : /*
                               2993                 :                :  * dumpDatabase:
                               2994                 :                :  *  dump the database definition
                               2995                 :                :  */
                               2996                 :                : static void
 3014                          2997                 :             62 : dumpDatabase(Archive *fout)
                               2998                 :                : {
                               2999                 :             62 :     DumpOptions *dopt = fout->dopt;
 8424 bruce@momjian.us         3000                 :             62 :     PQExpBuffer dbQry = createPQExpBuffer();
                               3001                 :             62 :     PQExpBuffer delQry = createPQExpBuffer();
                               3002                 :             62 :     PQExpBuffer creaQry = createPQExpBuffer();
 2274 tgl@sss.pgh.pa.us        3003                 :             62 :     PQExpBuffer labelq = createPQExpBuffer();
 4441 rhaas@postgresql.org     3004                 :             62 :     PGconn     *conn = GetConnection(fout);
                               3005                 :                :     PGresult   *res;
                               3006                 :                :     int         i_tableoid,
                               3007                 :                :                 i_oid,
                               3008                 :                :                 i_datname,
                               3009                 :                :                 i_datdba,
                               3010                 :                :                 i_encoding,
                               3011                 :                :                 i_datlocprovider,
                               3012                 :                :                 i_collate,
                               3013                 :                :                 i_ctype,
                               3014                 :                :                 i_datlocale,
                               3015                 :                :                 i_daticurules,
                               3016                 :                :                 i_frozenxid,
                               3017                 :                :                 i_minmxid,
                               3018                 :                :                 i_datacl,
                               3019                 :                :                 i_acldefault,
                               3020                 :                :                 i_datistemplate,
                               3021                 :                :                 i_datconnlimit,
                               3022                 :                :                 i_datcollversion,
                               3023                 :                :                 i_tablespace;
                               3024                 :                :     CatalogId   dbCatId;
                               3025                 :                :     DumpId      dbDumpId;
                               3026                 :                :     DumpableAcl dbdacl;
                               3027                 :                :     const char *datname,
                               3028                 :                :                *dba,
                               3029                 :                :                *encoding,
                               3030                 :                :                *datlocprovider,
                               3031                 :                :                *collate,
                               3032                 :                :                *ctype,
                               3033                 :                :                *locale,
                               3034                 :                :                *icurules,
                               3035                 :                :                *datistemplate,
                               3036                 :                :                *datconnlimit,
                               3037                 :                :                *tablespace;
                               3038                 :                :     uint32      frozenxid,
                               3039                 :                :                 minmxid;
                               3040                 :                :     char       *qdatname;
                               3041                 :                : 
 1840 peter@eisentraut.org     3042                 :             62 :     pg_log_info("saving database definition");
                               3043                 :                : 
                               3044                 :                :     /*
                               3045                 :                :      * Fetch the database-level properties for this database.
                               3046                 :                :      */
  586 drowley@postgresql.o     3047                 :             62 :     appendPQExpBufferStr(dbQry, "SELECT tableoid, oid, datname, "
                               3048                 :                :                          "datdba, "
                               3049                 :                :                          "pg_encoding_to_char(encoding) AS encoding, "
                               3050                 :                :                          "datcollate, datctype, datfrozenxid, "
                               3051                 :                :                          "datacl, acldefault('d', datdba) AS acldefault, "
                               3052                 :                :                          "datistemplate, datconnlimit, ");
  860 tgl@sss.pgh.pa.us        3053         [ +  - ]:             62 :     if (fout->remoteVersion >= 90300)
  586 drowley@postgresql.o     3054                 :             62 :         appendPQExpBufferStr(dbQry, "datminmxid, ");
                               3055                 :                :     else
  586 drowley@postgresql.o     3056                 :UBC           0 :         appendPQExpBufferStr(dbQry, "0 AS datminmxid, ");
   36 jdavis@postgresql.or     3057         [ +  - ]:GNC          62 :     if (fout->remoteVersion >= 170000)
                               3058                 :             62 :         appendPQExpBufferStr(dbQry, "datlocprovider, datlocale, datcollversion, ");
   36 jdavis@postgresql.or     3059         [ #  # ]:UNC           0 :     else if (fout->remoteVersion >= 150000)
                               3060                 :              0 :         appendPQExpBufferStr(dbQry, "datlocprovider, daticulocale AS datlocale, datcollversion, ");
                               3061                 :                :     else
                               3062                 :              0 :         appendPQExpBufferStr(dbQry, "'c' AS datlocprovider, NULL AS datlocale, NULL AS datcollversion, ");
  403 peter@eisentraut.org     3063         [ +  - ]:CBC          62 :     if (fout->remoteVersion >= 160000)
                               3064                 :             62 :         appendPQExpBufferStr(dbQry, "daticurules, ");
                               3065                 :                :     else
  403 peter@eisentraut.org     3066                 :UBC           0 :         appendPQExpBufferStr(dbQry, "NULL AS daticurules, ");
  586 drowley@postgresql.o     3067                 :CBC          62 :     appendPQExpBufferStr(dbQry,
                               3068                 :                :                          "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "
                               3069                 :                :                          "shobj_description(oid, 'pg_database') AS description "
                               3070                 :                :                          "FROM pg_database "
                               3071                 :                :                          "WHERE datname = current_database()");
                               3072                 :                : 
 4441 rhaas@postgresql.org     3073                 :             62 :     res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
                               3074                 :                : 
 7435 tgl@sss.pgh.pa.us        3075                 :             62 :     i_tableoid = PQfnumber(res, "tableoid");
                               3076                 :             62 :     i_oid = PQfnumber(res, "oid");
 2196 peter_e@gmx.net          3077                 :             62 :     i_datname = PQfnumber(res, "datname");
  835 tgl@sss.pgh.pa.us        3078                 :             62 :     i_datdba = PQfnumber(res, "datdba");
 8098                          3079                 :             62 :     i_encoding = PQfnumber(res, "encoding");
  759 peter@eisentraut.org     3080                 :             62 :     i_datlocprovider = PQfnumber(res, "datlocprovider");
 5681 heikki.linnakangas@i     3081                 :             62 :     i_collate = PQfnumber(res, "datcollate");
                               3082                 :             62 :     i_ctype = PQfnumber(res, "datctype");
   36 jdavis@postgresql.or     3083                 :GNC          62 :     i_datlocale = PQfnumber(res, "datlocale");
  403 peter@eisentraut.org     3084                 :CBC          62 :     i_daticurules = PQfnumber(res, "daticurules");
 5534 bruce@momjian.us         3085                 :             62 :     i_frozenxid = PQfnumber(res, "datfrozenxid");
 3574                          3086                 :             62 :     i_minmxid = PQfnumber(res, "datminmxid");
 2274 tgl@sss.pgh.pa.us        3087                 :             62 :     i_datacl = PQfnumber(res, "datacl");
  860                          3088                 :             62 :     i_acldefault = PQfnumber(res, "acldefault");
 2274                          3089                 :             62 :     i_datistemplate = PQfnumber(res, "datistemplate");
                               3090                 :             62 :     i_datconnlimit = PQfnumber(res, "datconnlimit");
  790 peter@eisentraut.org     3091                 :             62 :     i_datcollversion = PQfnumber(res, "datcollversion");
 7240 tgl@sss.pgh.pa.us        3092                 :             62 :     i_tablespace = PQfnumber(res, "tablespace");
                               3093                 :                : 
 7435                          3094                 :             62 :     dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid));
                               3095                 :             62 :     dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid));
 2196 peter_e@gmx.net          3096                 :             62 :     datname = PQgetvalue(res, 0, i_datname);
  835 tgl@sss.pgh.pa.us        3097                 :             62 :     dba = getRoleName(PQgetvalue(res, 0, i_datdba));
 8098                          3098                 :             62 :     encoding = PQgetvalue(res, 0, i_encoding);
  759 peter@eisentraut.org     3099                 :             62 :     datlocprovider = PQgetvalue(res, 0, i_datlocprovider);
 5682 heikki.linnakangas@i     3100                 :             62 :     collate = PQgetvalue(res, 0, i_collate);
                               3101                 :             62 :     ctype = PQgetvalue(res, 0, i_ctype);
   36 jdavis@postgresql.or     3102         [ +  + ]:GNC          62 :     if (!PQgetisnull(res, 0, i_datlocale))
                               3103                 :             14 :         locale = PQgetvalue(res, 0, i_datlocale);
                               3104                 :                :     else
                               3105                 :             48 :         locale = NULL;
  403 peter@eisentraut.org     3106         [ -  + ]:CBC          62 :     if (!PQgetisnull(res, 0, i_daticurules))
  403 peter@eisentraut.org     3107                 :UBC           0 :         icurules = PQgetvalue(res, 0, i_daticurules);
                               3108                 :                :     else
  403 peter@eisentraut.org     3109                 :CBC          62 :         icurules = NULL;
 5534 bruce@momjian.us         3110                 :             62 :     frozenxid = atooid(PQgetvalue(res, 0, i_frozenxid));
 3574                          3111                 :             62 :     minmxid = atooid(PQgetvalue(res, 0, i_minmxid));
  860 tgl@sss.pgh.pa.us        3112                 :             62 :     dbdacl.acl = PQgetvalue(res, 0, i_datacl);
                               3113                 :             62 :     dbdacl.acldefault = PQgetvalue(res, 0, i_acldefault);
 2274                          3114                 :             62 :     datistemplate = PQgetvalue(res, 0, i_datistemplate);
                               3115                 :             62 :     datconnlimit = PQgetvalue(res, 0, i_datconnlimit);
 7240                          3116                 :             62 :     tablespace = PQgetvalue(res, 0, i_tablespace);
                               3117                 :                : 
 2196 peter_e@gmx.net          3118                 :             62 :     qdatname = pg_strdup(fmtId(datname));
                               3119                 :                : 
                               3120                 :                :     /*
                               3121                 :                :      * Prepare the CREATE DATABASE command.  We must specify OID (if we want
                               3122                 :                :      * to preserve that), as well as the encoding, locale, and tablespace
                               3123                 :                :      * since those can't be altered later.  Other DB properties are left to
                               3124                 :                :      * the DATABASE PROPERTIES entry, so that they can be applied after
                               3125                 :                :      * reconnecting to the target DB.
                               3126                 :                :      */
  811 rhaas@postgresql.org     3127         [ +  + ]:             62 :     if (dopt->binary_upgrade)
                               3128                 :                :     {
                               3129                 :             13 :         appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0 OID = %u",
                               3130                 :                :                           qdatname, dbCatId.oid);
                               3131                 :                :     }
                               3132                 :                :     else
                               3133                 :                :     {
                               3134                 :             49 :         appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
                               3135                 :                :                           qdatname);
                               3136                 :                :     }
 7785 tgl@sss.pgh.pa.us        3137         [ +  - ]:             62 :     if (strlen(encoding) > 0)
                               3138                 :                :     {
 3800 heikki.linnakangas@i     3139                 :             62 :         appendPQExpBufferStr(creaQry, " ENCODING = ");
 4451 rhaas@postgresql.org     3140                 :             62 :         appendStringLiteralAH(creaQry, encoding, fout);
                               3141                 :                :     }
                               3142                 :                : 
  759 peter@eisentraut.org     3143                 :             62 :     appendPQExpBufferStr(creaQry, " LOCALE_PROVIDER = ");
   32 jdavis@postgresql.or     3144         [ +  + ]:GNC          62 :     if (datlocprovider[0] == 'b')
                               3145                 :             14 :         appendPQExpBufferStr(creaQry, "builtin");
                               3146         [ +  - ]:             48 :     else if (datlocprovider[0] == 'c')
  759 peter@eisentraut.org     3147                 :CBC          48 :         appendPQExpBufferStr(creaQry, "libc");
  759 peter@eisentraut.org     3148         [ #  # ]:LBC        (14) :     else if (datlocprovider[0] == 'i')
                               3149                 :           (14) :         appendPQExpBufferStr(creaQry, "icu");
                               3150                 :                :     else
  737 tgl@sss.pgh.pa.us        3151                 :UBC           0 :         pg_fatal("unrecognized locale provider: %s",
                               3152                 :                :                  datlocprovider);
                               3153                 :                : 
 1727 peter@eisentraut.org     3154   [ +  -  +  - ]:CBC          62 :     if (strlen(collate) > 0 && strcmp(collate, ctype) == 0)
                               3155                 :                :     {
                               3156                 :             62 :         appendPQExpBufferStr(creaQry, " LOCALE = ");
 4451 rhaas@postgresql.org     3157                 :             62 :         appendStringLiteralAH(creaQry, collate, fout);
                               3158                 :                :     }
                               3159                 :                :     else
                               3160                 :                :     {
 1727 peter@eisentraut.org     3161         [ #  # ]:UBC           0 :         if (strlen(collate) > 0)
                               3162                 :                :         {
                               3163                 :              0 :             appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
                               3164                 :              0 :             appendStringLiteralAH(creaQry, collate, fout);
                               3165                 :                :         }
                               3166         [ #  # ]:              0 :         if (strlen(ctype) > 0)
                               3167                 :                :         {
                               3168                 :              0 :             appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
                               3169                 :              0 :             appendStringLiteralAH(creaQry, ctype, fout);
                               3170                 :                :         }
                               3171                 :                :     }
   36 jdavis@postgresql.or     3172         [ +  + ]:GNC          62 :     if (locale)
                               3173                 :                :     {
   32                          3174         [ +  - ]:             14 :         if (datlocprovider[0] == 'b')
                               3175                 :             14 :             appendPQExpBufferStr(creaQry, " BUILTIN_LOCALE = ");
                               3176                 :                :         else
   32 jdavis@postgresql.or     3177                 :UNC           0 :             appendPQExpBufferStr(creaQry, " ICU_LOCALE = ");
                               3178                 :                : 
   36 jdavis@postgresql.or     3179                 :GNC          14 :         appendStringLiteralAH(creaQry, locale, fout);
                               3180                 :                :     }
                               3181                 :                : 
  403 peter@eisentraut.org     3182         [ -  + ]:CBC          62 :     if (icurules)
                               3183                 :                :     {
  403 peter@eisentraut.org     3184                 :UBC           0 :         appendPQExpBufferStr(creaQry, " ICU_RULES = ");
                               3185                 :              0 :         appendStringLiteralAH(creaQry, icurules, fout);
                               3186                 :                :     }
                               3187                 :                : 
                               3188                 :                :     /*
                               3189                 :                :      * For binary upgrade, carry over the collation version.  For normal
                               3190                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                               3191                 :                :      */
  790 peter@eisentraut.org     3192         [ +  + ]:CBC          62 :     if (dopt->binary_upgrade)
                               3193                 :                :     {
                               3194         [ +  - ]:             13 :         if (!PQgetisnull(res, 0, i_datcollversion))
                               3195                 :                :         {
                               3196                 :             13 :             appendPQExpBufferStr(creaQry, " COLLATION_VERSION = ");
                               3197                 :             13 :             appendStringLiteralAH(creaQry,
                               3198                 :                :                                   PQgetvalue(res, 0, i_datcollversion),
                               3199                 :                :                                   fout);
                               3200                 :                :         }
                               3201                 :                :     }
                               3202                 :                : 
                               3203                 :                :     /*
                               3204                 :                :      * Note: looking at dopt->outputNoTablespaces here is completely the wrong
                               3205                 :                :      * thing; the decision whether to specify a tablespace should be left till
                               3206                 :                :      * pg_restore, so that pg_restore --no-tablespaces applies.  Ideally we'd
                               3207                 :                :      * label the DATABASE entry with the tablespace and let the normal
                               3208                 :                :      * tablespace selection logic work ... but CREATE DATABASE doesn't pay
                               3209                 :                :      * attention to default_tablespace, so that won't work.
                               3210                 :                :      */
 2775 tgl@sss.pgh.pa.us        3211   [ +  -  -  + ]:             62 :     if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0 &&
 2775 tgl@sss.pgh.pa.us        3212         [ #  # ]:UBC           0 :         !dopt->outputNoTablespaces)
 7118                          3213                 :              0 :         appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                               3214                 :                :                           fmtId(tablespace));
 3800 heikki.linnakangas@i     3215                 :CBC          62 :     appendPQExpBufferStr(creaQry, ";\n");
                               3216                 :                : 
 8098 tgl@sss.pgh.pa.us        3217                 :             62 :     appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
                               3218                 :                :                       qdatname);
                               3219                 :                : 
 7435                          3220                 :             62 :     dbDumpId = createDumpId();
                               3221                 :                : 
 4451 rhaas@postgresql.org     3222                 :             62 :     ArchiveEntry(fout,
                               3223                 :                :                  dbCatId,       /* catalog ID */
                               3224                 :                :                  dbDumpId,      /* dump ID */
 1899 alvherre@alvh.no-ip.     3225                 :             62 :                  ARCHIVE_OPTS(.tag = datname,
                               3226                 :                :                               .owner = dba,
                               3227                 :                :                               .description = "DATABASE",
                               3228                 :                :                               .section = SECTION_PRE_DATA,
                               3229                 :                :                               .createStmt = creaQry->data,
                               3230                 :                :                               .dropStmt = delQry->data));
                               3231                 :                : 
                               3232                 :                :     /* Compute correct tag for archive entry */
 2274 tgl@sss.pgh.pa.us        3233                 :             62 :     appendPQExpBuffer(labelq, "DATABASE %s", qdatname);
                               3234                 :                : 
                               3235                 :                :     /* Dump DB comment if any */
                               3236                 :                :     {
                               3237                 :                :         /*
                               3238                 :                :          * 8.2 and up keep comments on shared objects in a shared table, so we
                               3239                 :                :          * cannot use the dumpComment() code used for other database objects.
                               3240                 :                :          * Be careful that the ArchiveEntry parameters match that function.
                               3241                 :                :          */
                               3242                 :             62 :         char       *comment = PQgetvalue(res, 0, PQfnumber(res, "description"));
                               3243                 :                : 
 2271                          3244   [ +  -  +  +  :             62 :         if (comment && *comment && !dopt->no_comments)
                                              +  - ]
                               3245                 :                :         {
 2274                          3246                 :             27 :             resetPQExpBuffer(dbQry);
                               3247                 :                : 
                               3248                 :                :             /*
                               3249                 :                :              * Generates warning when loaded into a differently-named
                               3250                 :                :              * database.
                               3251                 :                :              */
                               3252                 :             27 :             appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", qdatname);
                               3253                 :             27 :             appendStringLiteralAH(dbQry, comment, fout);
                               3254                 :             27 :             appendPQExpBufferStr(dbQry, ";\n");
                               3255                 :                : 
                               3256                 :             27 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3257                 :             27 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3258                 :                :                                       .owner = dba,
                               3259                 :                :                                       .description = "COMMENT",
                               3260                 :                :                                       .section = SECTION_NONE,
                               3261                 :                :                                       .createStmt = dbQry->data,
                               3262                 :                :                                       .deps = &dbDumpId,
                               3263                 :                :                                       .nDeps = 1));
                               3264                 :                :         }
                               3265                 :                :     }
                               3266                 :                : 
                               3267                 :                :     /* Dump DB security label, if enabled */
  852 tgl@sss.pgh.pa.us        3268         [ +  - ]:             62 :     if (!dopt->no_security_labels)
                               3269                 :                :     {
                               3270                 :                :         PGresult   *shres;
                               3271                 :                :         PQExpBuffer seclabelQry;
                               3272                 :                : 
 2274                          3273                 :             62 :         seclabelQry = createPQExpBuffer();
                               3274                 :                : 
 1328 peter@eisentraut.org     3275                 :             62 :         buildShSecLabelQuery("pg_database", dbCatId.oid, seclabelQry);
 2274 tgl@sss.pgh.pa.us        3276                 :             62 :         shres = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
                               3277                 :             62 :         resetPQExpBuffer(seclabelQry);
                               3278                 :             62 :         emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname);
                               3279         [ -  + ]:             62 :         if (seclabelQry->len > 0)
 2274 tgl@sss.pgh.pa.us        3280                 :UBC           0 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3281                 :              0 :                          ARCHIVE_OPTS(.tag = labelq->data,
                               3282                 :                :                                       .owner = dba,
                               3283                 :                :                                       .description = "SECURITY LABEL",
                               3284                 :                :                                       .section = SECTION_NONE,
                               3285                 :                :                                       .createStmt = seclabelQry->data,
                               3286                 :                :                                       .deps = &dbDumpId,
                               3287                 :                :                                       .nDeps = 1));
 2274 tgl@sss.pgh.pa.us        3288                 :CBC          62 :         destroyPQExpBuffer(seclabelQry);
                               3289                 :             62 :         PQclear(shres);
                               3290                 :                :     }
                               3291                 :                : 
                               3292                 :                :     /*
                               3293                 :                :      * Dump ACL if any.  Note that we do not support initial privileges
                               3294                 :                :      * (pg_init_privs) on databases.
                               3295                 :                :      */
  860                          3296                 :             62 :     dbdacl.privtype = 0;
                               3297                 :             62 :     dbdacl.initprivs = NULL;
                               3298                 :                : 
 1373                          3299                 :             62 :     dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
                               3300                 :                :             qdatname, NULL, NULL,
                               3301                 :                :             NULL, dba, &dbdacl);
                               3302                 :                : 
                               3303                 :                :     /*
                               3304                 :                :      * Now construct a DATABASE PROPERTIES archive entry to restore any
                               3305                 :                :      * non-default database-level properties.  (The reason this must be
                               3306                 :                :      * separate is that we cannot put any additional commands into the TOC
                               3307                 :                :      * entry that has CREATE DATABASE.  pg_restore would execute such a group
                               3308                 :                :      * in an implicit transaction block, and the backend won't allow CREATE
                               3309                 :                :      * DATABASE in that context.)
                               3310                 :                :      */
 2274                          3311                 :             62 :     resetPQExpBuffer(creaQry);
                               3312                 :             62 :     resetPQExpBuffer(delQry);
                               3313                 :                : 
                               3314   [ +  -  -  + ]:             62 :     if (strlen(datconnlimit) > 0 && strcmp(datconnlimit, "-1") != 0)
 2274 tgl@sss.pgh.pa.us        3315                 :UBC           0 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s CONNECTION LIMIT = %s;\n",
                               3316                 :                :                           qdatname, datconnlimit);
                               3317                 :                : 
 2274 tgl@sss.pgh.pa.us        3318         [ +  + ]:CBC          62 :     if (strcmp(datistemplate, "t") == 0)
                               3319                 :                :     {
                               3320                 :              4 :         appendPQExpBuffer(creaQry, "ALTER DATABASE %s IS_TEMPLATE = true;\n",
                               3321                 :                :                           qdatname);
                               3322                 :                : 
                               3323                 :                :         /*
                               3324                 :                :          * The backend won't accept DROP DATABASE on a template database.  We
                               3325                 :                :          * can deal with that by removing the template marking before the DROP
                               3326                 :                :          * gets issued.  We'd prefer to use ALTER DATABASE IF EXISTS here, but
                               3327                 :                :          * since no such command is currently supported, fake it with a direct
                               3328                 :                :          * UPDATE on pg_database.
                               3329                 :                :          */
                               3330                 :              4 :         appendPQExpBufferStr(delQry, "UPDATE pg_catalog.pg_database "
                               3331                 :                :                              "SET datistemplate = false WHERE datname = ");
                               3332                 :              4 :         appendStringLiteralAH(delQry, datname, fout);
                               3333                 :              4 :         appendPQExpBufferStr(delQry, ";\n");
                               3334                 :                :     }
                               3335                 :                : 
                               3336                 :                :     /*
                               3337                 :                :      * We do not restore pg_database.dathasloginevt because it is set
                               3338                 :                :      * automatically on login event trigger creation.
                               3339                 :                :      */
                               3340                 :                : 
                               3341                 :                :     /* Add database-specific SET options */
                               3342                 :             62 :     dumpDatabaseConfig(fout, creaQry, datname, dbCatId.oid);
                               3343                 :                : 
                               3344                 :                :     /*
                               3345                 :                :      * We stick this binary-upgrade query into the DATABASE PROPERTIES archive
                               3346                 :                :      * entry, too, for lack of a better place.
                               3347                 :                :      */
                               3348         [ +  + ]:             62 :     if (dopt->binary_upgrade)
                               3349                 :                :     {
                               3350                 :             13 :         appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid and datminmxid.\n");
                               3351                 :             13 :         appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
                               3352                 :                :                           "SET datfrozenxid = '%u', datminmxid = '%u'\n"
                               3353                 :                :                           "WHERE datname = ",
                               3354                 :                :                           frozenxid, minmxid);
                               3355                 :             13 :         appendStringLiteralAH(creaQry, datname, fout);
                               3356                 :             13 :         appendPQExpBufferStr(creaQry, ";\n");
                               3357                 :                :     }
                               3358                 :                : 
                               3359         [ +  + ]:             62 :     if (creaQry->len > 0)
                               3360                 :             17 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3361                 :             17 :                      ARCHIVE_OPTS(.tag = datname,
                               3362                 :                :                                   .owner = dba,
                               3363                 :                :                                   .description = "DATABASE PROPERTIES",
                               3364                 :                :                                   .section = SECTION_PRE_DATA,
                               3365                 :                :                                   .createStmt = creaQry->data,
                               3366                 :                :                                   .dropStmt = delQry->data,
                               3367                 :                :                                   .deps = &dbDumpId));
                               3368                 :                : 
                               3369                 :                :     /*
                               3370                 :                :      * pg_largeobject comes from the old system intact, so set its
                               3371                 :                :      * relfrozenxids, relminmxids and relfilenode.
                               3372                 :                :      */
 3470                          3373         [ +  + ]:             62 :     if (dopt->binary_upgrade)
                               3374                 :                :     {
                               3375                 :                :         PGresult   *lo_res;
 5382 bruce@momjian.us         3376                 :             13 :         PQExpBuffer loFrozenQry = createPQExpBuffer();
                               3377                 :             13 :         PQExpBuffer loOutQry = createPQExpBuffer();
  625 rhaas@postgresql.org     3378                 :             13 :         PQExpBuffer loHorizonQry = createPQExpBuffer();
                               3379                 :                :         int         ii_relfrozenxid,
                               3380                 :                :                     ii_relfilenode,
                               3381                 :                :                     ii_oid,
                               3382                 :                :                     ii_relminmxid;
                               3383                 :                : 
                               3384                 :                :         /*
                               3385                 :                :          * pg_largeobject
                               3386                 :                :          */
 3574 bruce@momjian.us         3387         [ +  - ]:             13 :         if (fout->remoteVersion >= 90300)
  646 rhaas@postgresql.org     3388                 :             13 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid, relfilenode, oid\n"
                               3389                 :                :                               "FROM pg_catalog.pg_class\n"
                               3390                 :                :                               "WHERE oid IN (%u, %u);\n",
                               3391                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId);
                               3392                 :                :         else
  646 rhaas@postgresql.org     3393                 :UBC           0 :             appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid, relfilenode, oid\n"
                               3394                 :                :                               "FROM pg_catalog.pg_class\n"
                               3395                 :                :                               "WHERE oid IN (%u, %u);\n",
                               3396                 :                :                               LargeObjectRelationId, LargeObjectLOidPNIndexId);
                               3397                 :                : 
  646 rhaas@postgresql.org     3398                 :CBC          13 :         lo_res = ExecuteSqlQuery(fout, loFrozenQry->data, PGRES_TUPLES_OK);
                               3399                 :                : 
  603 drowley@postgresql.o     3400                 :             13 :         ii_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
                               3401                 :             13 :         ii_relminmxid = PQfnumber(lo_res, "relminmxid");
                               3402                 :             13 :         ii_relfilenode = PQfnumber(lo_res, "relfilenode");
                               3403                 :             13 :         ii_oid = PQfnumber(lo_res, "oid");
                               3404                 :                : 
  625 rhaas@postgresql.org     3405                 :             13 :         appendPQExpBufferStr(loHorizonQry, "\n-- For binary upgrade, set pg_largeobject relfrozenxid and relminmxid\n");
                               3406                 :             13 :         appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, preserve pg_largeobject and index relfilenodes\n");
  646                          3407         [ +  + ]:             39 :         for (int i = 0; i < PQntuples(lo_res); ++i)
                               3408                 :                :         {
                               3409                 :                :             Oid         oid;
                               3410                 :                :             RelFileNumber relfilenumber;
                               3411                 :                : 
  625                          3412                 :             26 :             appendPQExpBuffer(loHorizonQry, "UPDATE pg_catalog.pg_class\n"
                               3413                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                               3414                 :                :                               "WHERE oid = %u;\n",
  603 drowley@postgresql.o     3415                 :             26 :                               atooid(PQgetvalue(lo_res, i, ii_relfrozenxid)),
                               3416                 :             26 :                               atooid(PQgetvalue(lo_res, i, ii_relminmxid)),
                               3417                 :             26 :                               atooid(PQgetvalue(lo_res, i, ii_oid)));
                               3418                 :                : 
                               3419                 :             26 :             oid = atooid(PQgetvalue(lo_res, i, ii_oid));
  564 rhaas@postgresql.org     3420                 :             26 :             relfilenumber = atooid(PQgetvalue(lo_res, i, ii_relfilenode));
                               3421                 :                : 
  626                          3422         [ +  + ]:             26 :             if (oid == LargeObjectRelationId)
  625                          3423                 :             13 :                 appendPQExpBuffer(loOutQry,
                               3424                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               3425                 :                :                                   relfilenumber);
  626                          3426         [ +  - ]:             13 :             else if (oid == LargeObjectLOidPNIndexId)
  625                          3427                 :             13 :                 appendPQExpBuffer(loOutQry,
                               3428                 :                :                                   "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               3429                 :                :                                   relfilenumber);
                               3430                 :                :         }
                               3431                 :                : 
                               3432                 :             13 :         appendPQExpBufferStr(loOutQry,
                               3433                 :                :                              "TRUNCATE pg_catalog.pg_largeobject;\n");
                               3434                 :             13 :         appendPQExpBufferStr(loOutQry, loHorizonQry->data);
                               3435                 :                : 
 4451                          3436                 :             13 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3437                 :             13 :                      ARCHIVE_OPTS(.tag = "pg_largeobject",
                               3438                 :                :                                   .description = "pg_largeobject",
                               3439                 :                :                                   .section = SECTION_PRE_DATA,
                               3440                 :                :                                   .createStmt = loOutQry->data));
                               3441                 :                : 
 5382 bruce@momjian.us         3442                 :             13 :         PQclear(lo_res);
                               3443                 :                : 
                               3444                 :             13 :         destroyPQExpBuffer(loFrozenQry);
  625 rhaas@postgresql.org     3445                 :             13 :         destroyPQExpBuffer(loHorizonQry);
 5382 bruce@momjian.us         3446                 :             13 :         destroyPQExpBuffer(loOutQry);
                               3447                 :                :     }
                               3448                 :                : 
 3374 andres@anarazel.de       3449                 :             62 :     PQclear(res);
                               3450                 :                : 
 2274 tgl@sss.pgh.pa.us        3451                 :             62 :     free(qdatname);
 8290                          3452                 :             62 :     destroyPQExpBuffer(dbQry);
                               3453                 :             62 :     destroyPQExpBuffer(delQry);
                               3454                 :             62 :     destroyPQExpBuffer(creaQry);
 2274                          3455                 :             62 :     destroyPQExpBuffer(labelq);
 8657 pjw@rhyme.com.au         3456                 :             62 : }
                               3457                 :                : 
                               3458                 :                : /*
                               3459                 :                :  * Collect any database-specific or role-and-database-specific SET options
                               3460                 :                :  * for this database, and append them to outbuf.
                               3461                 :                :  */
                               3462                 :                : static void
 2274 tgl@sss.pgh.pa.us        3463                 :             62 : dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf,
                               3464                 :                :                    const char *dbname, Oid dboid)
                               3465                 :                : {
                               3466                 :             62 :     PGconn     *conn = GetConnection(AH);
                               3467                 :             62 :     PQExpBuffer buf = createPQExpBuffer();
                               3468                 :                :     PGresult   *res;
                               3469                 :                : 
                               3470                 :                :     /* First collect database-specific options */
  333 akorotkov@postgresql     3471                 :             62 :     printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
                               3472                 :                :                       "WHERE setrole = 0 AND setdatabase = '%u'::oid",
                               3473                 :                :                       dboid);
                               3474                 :                : 
  852 tgl@sss.pgh.pa.us        3475                 :             62 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3476                 :                : 
                               3477         [ +  + ]:             92 :     for (int i = 0; i < PQntuples(res); i++)
  333 akorotkov@postgresql     3478                 :             30 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
                               3479                 :                :                                "DATABASE", dbname, NULL, NULL,
                               3480                 :                :                                outbuf);
                               3481                 :                : 
  852 tgl@sss.pgh.pa.us        3482                 :             62 :     PQclear(res);
                               3483                 :                : 
                               3484                 :                :     /* Now look for role-and-database-specific options */
  333 akorotkov@postgresql     3485                 :             62 :     printfPQExpBuffer(buf, "SELECT rolname, unnest(setconfig) "
                               3486                 :                :                       "FROM pg_db_role_setting s, pg_roles r "
                               3487                 :                :                       "WHERE setrole = r.oid AND setdatabase = '%u'::oid",
                               3488                 :                :                       dboid);
                               3489                 :                : 
  852 tgl@sss.pgh.pa.us        3490                 :             62 :     res = ExecuteSqlQuery(AH, buf->data, PGRES_TUPLES_OK);
                               3491                 :                : 
                               3492         [ -  + ]:             62 :     for (int i = 0; i < PQntuples(res); i++)
  333 akorotkov@postgresql     3493                 :UBC           0 :         makeAlterConfigCommand(conn, PQgetvalue(res, i, 1),
  852 tgl@sss.pgh.pa.us        3494                 :              0 :                                "ROLE", PQgetvalue(res, i, 0),
                               3495                 :                :                                "DATABASE", dbname,
                               3496                 :                :                                outbuf);
                               3497                 :                : 
  852 tgl@sss.pgh.pa.us        3498                 :CBC          62 :     PQclear(res);
                               3499                 :                : 
 2274                          3500                 :             62 :     destroyPQExpBuffer(buf);
                               3501                 :             62 : }
                               3502                 :                : 
                               3503                 :                : /*
                               3504                 :                :  * dumpEncoding: put the correct encoding into the archive
                               3505                 :                :  */
                               3506                 :                : static void
 7355                          3507                 :            155 : dumpEncoding(Archive *AH)
                               3508                 :                : {
 6531                          3509                 :            155 :     const char *encname = pg_encoding_to_char(AH->encoding);
                               3510                 :            155 :     PQExpBuffer qry = createPQExpBuffer();
                               3511                 :                : 
 1840 peter@eisentraut.org     3512                 :            155 :     pg_log_info("saving encoding = %s", encname);
                               3513                 :                : 
 3800 heikki.linnakangas@i     3514                 :            155 :     appendPQExpBufferStr(qry, "SET client_encoding = ");
 6531 tgl@sss.pgh.pa.us        3515                 :            155 :     appendStringLiteralAH(qry, encname, AH);
 3800 heikki.linnakangas@i     3516                 :            155 :     appendPQExpBufferStr(qry, ";\n");
                               3517                 :                : 
 7355 tgl@sss.pgh.pa.us        3518                 :            155 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3519                 :            155 :                  ARCHIVE_OPTS(.tag = "ENCODING",
                               3520                 :                :                               .description = "ENCODING",
                               3521                 :                :                               .section = SECTION_PRE_DATA,
                               3522                 :                :                               .createStmt = qry->data));
                               3523                 :                : 
 7355 tgl@sss.pgh.pa.us        3524                 :            155 :     destroyPQExpBuffer(qry);
                               3525                 :            155 : }
                               3526                 :                : 
                               3527                 :                : 
                               3528                 :                : /*
                               3529                 :                :  * dumpStdStrings: put the correct escape string behavior into the archive
                               3530                 :                :  */
                               3531                 :                : static void
 6533 bruce@momjian.us         3532                 :            155 : dumpStdStrings(Archive *AH)
                               3533                 :                : {
 6531 tgl@sss.pgh.pa.us        3534         [ +  - ]:            155 :     const char *stdstrings = AH->std_strings ? "on" : "off";
                               3535                 :            155 :     PQExpBuffer qry = createPQExpBuffer();
                               3536                 :                : 
 1840 peter@eisentraut.org     3537                 :            155 :     pg_log_info("saving standard_conforming_strings = %s",
                               3538                 :                :                 stdstrings);
                               3539                 :                : 
 6531 tgl@sss.pgh.pa.us        3540                 :            155 :     appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n",
                               3541                 :                :                       stdstrings);
                               3542                 :                : 
 6533 bruce@momjian.us         3543                 :            155 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3544                 :            155 :                  ARCHIVE_OPTS(.tag = "STDSTRINGS",
                               3545                 :                :                               .description = "STDSTRINGS",
                               3546                 :                :                               .section = SECTION_PRE_DATA,
                               3547                 :                :                               .createStmt = qry->data));
                               3548                 :                : 
 6533 bruce@momjian.us         3549                 :            155 :     destroyPQExpBuffer(qry);
                               3550                 :            155 : }
                               3551                 :                : 
                               3552                 :                : /*
                               3553                 :                :  * dumpSearchPath: record the active search_path in the archive
                               3554                 :                :  */
                               3555                 :                : static void
 2239 tgl@sss.pgh.pa.us        3556                 :            155 : dumpSearchPath(Archive *AH)
                               3557                 :                : {
                               3558                 :            155 :     PQExpBuffer qry = createPQExpBuffer();
                               3559                 :            155 :     PQExpBuffer path = createPQExpBuffer();
                               3560                 :                :     PGresult   *res;
                               3561                 :            155 :     char      **schemanames = NULL;
                               3562                 :            155 :     int         nschemanames = 0;
                               3563                 :                :     int         i;
                               3564                 :                : 
                               3565                 :                :     /*
                               3566                 :                :      * We use the result of current_schemas(), not the search_path GUC,
                               3567                 :                :      * because that might contain wildcards such as "$user", which won't
                               3568                 :                :      * necessarily have the same value during restore.  Also, this way avoids
                               3569                 :                :      * listing schemas that may appear in search_path but not actually exist,
                               3570                 :                :      * which seems like a prudent exclusion.
                               3571                 :                :      */
                               3572                 :            155 :     res = ExecuteSqlQueryForSingleRow(AH,
                               3573                 :                :                                       "SELECT pg_catalog.current_schemas(false)");
                               3574                 :                : 
                               3575         [ -  + ]:            155 :     if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames))
  737 tgl@sss.pgh.pa.us        3576                 :UBC           0 :         pg_fatal("could not parse result of current_schemas()");
                               3577                 :                : 
                               3578                 :                :     /*
                               3579                 :                :      * We use set_config(), not a simple "SET search_path" command, because
                               3580                 :                :      * the latter has less-clean behavior if the search path is empty.  While
                               3581                 :                :      * that's likely to get fixed at some point, it seems like a good idea to
                               3582                 :                :      * be as backwards-compatible as possible in what we put into archives.
                               3583                 :                :      */
 2239 tgl@sss.pgh.pa.us        3584         [ -  + ]:CBC         155 :     for (i = 0; i < nschemanames; i++)
                               3585                 :                :     {
 2239 tgl@sss.pgh.pa.us        3586         [ #  # ]:UBC           0 :         if (i > 0)
                               3587                 :              0 :             appendPQExpBufferStr(path, ", ");
                               3588                 :              0 :         appendPQExpBufferStr(path, fmtId(schemanames[i]));
                               3589                 :                :     }
                               3590                 :                : 
 2239 tgl@sss.pgh.pa.us        3591                 :CBC         155 :     appendPQExpBufferStr(qry, "SELECT pg_catalog.set_config('search_path', ");
                               3592                 :            155 :     appendStringLiteralAH(qry, path->data, AH);
                               3593                 :            155 :     appendPQExpBufferStr(qry, ", false);\n");
                               3594                 :                : 
 1840 peter@eisentraut.org     3595                 :            155 :     pg_log_info("saving search_path = %s", path->data);
                               3596                 :                : 
 2239 tgl@sss.pgh.pa.us        3597                 :            155 :     ArchiveEntry(AH, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.     3598                 :            155 :                  ARCHIVE_OPTS(.tag = "SEARCHPATH",
                               3599                 :                :                               .description = "SEARCHPATH",
                               3600                 :                :                               .section = SECTION_PRE_DATA,
                               3601                 :                :                               .createStmt = qry->data));
                               3602                 :                : 
                               3603                 :                :     /* Also save it in AH->searchpath, in case we're doing plain text dump */
 2239 tgl@sss.pgh.pa.us        3604                 :            155 :     AH->searchpath = pg_strdup(qry->data);
                               3605                 :                : 
  668 peter@eisentraut.org     3606                 :            155 :     free(schemanames);
 2239 tgl@sss.pgh.pa.us        3607                 :            155 :     PQclear(res);
                               3608                 :            155 :     destroyPQExpBuffer(qry);
                               3609                 :            155 :     destroyPQExpBuffer(path);
                               3610                 :            155 : }
                               3611                 :                : 
                               3612                 :                : 
                               3613                 :                : /*
                               3614                 :                :  * getLOs:
                               3615                 :                :  *  Collect schema-level data about large objects
                               3616                 :                :  */
                               3617                 :                : static void
  496 peter@eisentraut.org     3618                 :            131 : getLOs(Archive *fout)
                               3619                 :                : {
 2930 sfrost@snowman.net       3620                 :            131 :     DumpOptions *dopt = fout->dopt;
  496 peter@eisentraut.org     3621                 :            131 :     PQExpBuffer loQry = createPQExpBuffer();
                               3622                 :                :     PGresult   *res;
                               3623                 :                :     int         ntups;
                               3624                 :                :     int         i;
                               3625                 :                :     int         n;
                               3626                 :                :     int         i_oid;
                               3627                 :                :     int         i_lomowner;
                               3628                 :                :     int         i_lomacl;
                               3629                 :                :     int         i_acldefault;
                               3630                 :                : 
 1840                          3631                 :            131 :     pg_log_info("reading large objects");
                               3632                 :                : 
                               3633                 :                :     /*
                               3634                 :                :      * Fetch LO OIDs and owner/ACL data.  Order the data so that all the blobs
                               3635                 :                :      * with the same owner/ACL appear together.
                               3636                 :                :      */
  496                          3637                 :            131 :     appendPQExpBufferStr(loQry,
                               3638                 :                :                          "SELECT oid, lomowner, lomacl, "
                               3639                 :                :                          "acldefault('L', lomowner) AS acldefault "
                               3640                 :                :                          "FROM pg_largeobject_metadata "
                               3641                 :                :                          "ORDER BY lomowner, lomacl::pg_catalog.text, oid");
                               3642                 :                : 
                               3643                 :            131 :     res = ExecuteSqlQuery(fout, loQry->data, PGRES_TUPLES_OK);
                               3644                 :                : 
 2930 sfrost@snowman.net       3645                 :            131 :     i_oid = PQfnumber(res, "oid");
  835 tgl@sss.pgh.pa.us        3646                 :            131 :     i_lomowner = PQfnumber(res, "lomowner");
 2930 sfrost@snowman.net       3647                 :            131 :     i_lomacl = PQfnumber(res, "lomacl");
  860 tgl@sss.pgh.pa.us        3648                 :            131 :     i_acldefault = PQfnumber(res, "acldefault");
                               3649                 :                : 
 5169                          3650                 :            131 :     ntups = PQntuples(res);
                               3651                 :                : 
                               3652                 :                :     /*
                               3653                 :                :      * Group the blobs into suitably-sized groups that have the same owner and
                               3654                 :                :      * ACL setting, and build a metadata and a data DumpableObject for each
                               3655                 :                :      * group.  (If we supported initprivs for blobs, we'd have to insist that
                               3656                 :                :      * groups also share initprivs settings, since the DumpableObject only has
                               3657                 :                :      * room for one.)  i is the index of the first tuple in the current group,
                               3658                 :                :      * and n is the number of tuples we include in the group.
                               3659                 :                :      */
   13 tgl@sss.pgh.pa.us        3660         [ +  + ]:GNC         210 :     for (i = 0; i < ntups; i += n)
                               3661                 :                :     {
                               3662                 :             79 :         Oid         thisoid = atooid(PQgetvalue(res, i, i_oid));
                               3663                 :             79 :         char       *thisowner = PQgetvalue(res, i, i_lomowner);
                               3664                 :             79 :         char       *thisacl = PQgetvalue(res, i, i_lomacl);
                               3665                 :                :         LoInfo     *loinfo;
                               3666                 :                :         DumpableObject *lodata;
                               3667                 :                :         char        namebuf[64];
                               3668                 :                : 
                               3669                 :                :         /* Scan to find first tuple not to be included in group */
                               3670                 :             79 :         n = 1;
                               3671   [ +  -  +  + ]:             89 :         while (n < MAX_BLOBS_PER_ARCHIVE_ENTRY && i + n < ntups)
                               3672                 :                :         {
                               3673         [ +  - ]:             47 :             if (strcmp(thisowner, PQgetvalue(res, i + n, i_lomowner)) != 0 ||
                               3674         [ +  + ]:             47 :                 strcmp(thisacl, PQgetvalue(res, i + n, i_lomacl)) != 0)
                               3675                 :                :                 break;
                               3676                 :             10 :             n++;
                               3677                 :                :         }
                               3678                 :                : 
                               3679                 :                :         /* Build the metadata DumpableObject */
                               3680                 :             79 :         loinfo = (LoInfo *) pg_malloc(offsetof(LoInfo, looids) + n * sizeof(Oid));
                               3681                 :                : 
                               3682                 :             79 :         loinfo->dobj.objType = DO_LARGE_OBJECT;
                               3683                 :             79 :         loinfo->dobj.catId.tableoid = LargeObjectRelationId;
                               3684                 :             79 :         loinfo->dobj.catId.oid = thisoid;
                               3685                 :             79 :         AssignDumpId(&loinfo->dobj);
                               3686                 :                : 
                               3687         [ +  + ]:             79 :         if (n > 1)
                               3688                 :              5 :             snprintf(namebuf, sizeof(namebuf), "%u..%u", thisoid,
                               3689                 :              5 :                      atooid(PQgetvalue(res, i + n - 1, i_oid)));
                               3690                 :                :         else
                               3691                 :             74 :             snprintf(namebuf, sizeof(namebuf), "%u", thisoid);
                               3692                 :             79 :         loinfo->dobj.name = pg_strdup(namebuf);
                               3693                 :             79 :         loinfo->dacl.acl = pg_strdup(thisacl);
                               3694                 :             79 :         loinfo->dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               3695                 :             79 :         loinfo->dacl.privtype = 0;
                               3696                 :             79 :         loinfo->dacl.initprivs = NULL;
                               3697                 :             79 :         loinfo->rolname = getRoleName(thisowner);
                               3698                 :             79 :         loinfo->numlos = n;
                               3699                 :             79 :         loinfo->looids[0] = thisoid;
                               3700                 :                :         /* Collect OIDs of the remaining blobs in this group */
                               3701         [ +  + ]:             89 :         for (int k = 1; k < n; k++)
                               3702                 :                :         {
                               3703                 :                :             CatalogId   extraID;
                               3704                 :                : 
                               3705                 :             10 :             loinfo->looids[k] = atooid(PQgetvalue(res, i + k, i_oid));
                               3706                 :                : 
                               3707                 :                :             /* Make sure we can look up loinfo by any of the blobs' OIDs */
                               3708                 :             10 :             extraID.tableoid = LargeObjectRelationId;
                               3709                 :             10 :             extraID.oid = loinfo->looids[k];
                               3710                 :             10 :             recordAdditionalCatalogID(extraID, &loinfo->dobj);
                               3711                 :                :         }
                               3712                 :                : 
                               3713                 :                :         /* LOs have data */
                               3714                 :             79 :         loinfo->dobj.components |= DUMP_COMPONENT_DATA;
                               3715                 :                : 
                               3716                 :                :         /* Mark whether LO group has a non-empty ACL */
  860 tgl@sss.pgh.pa.us        3717         [ +  + ]:CBC          79 :         if (!PQgetisnull(res, i, i_lomacl))
   13 tgl@sss.pgh.pa.us        3718                 :GNC          37 :             loinfo->dobj.components |= DUMP_COMPONENT_ACL;
                               3719                 :                : 
                               3720                 :                :         /*
                               3721                 :                :          * In binary-upgrade mode for LOs, we do *not* dump out the LO data,
                               3722                 :                :          * as it will be copied by pg_upgrade, which simply copies the
                               3723                 :                :          * pg_largeobject table. We *do* however dump out anything but the
                               3724                 :                :          * data, as pg_upgrade copies just pg_largeobject, but not
                               3725                 :                :          * pg_largeobject_metadata, after the dump is restored.
                               3726                 :                :          */
 2596 sfrost@snowman.net       3727         [ +  + ]:CBC          79 :         if (dopt->binary_upgrade)
   13 tgl@sss.pgh.pa.us        3728                 :GNC           3 :             loinfo->dobj.dump &= ~DUMP_COMPONENT_DATA;
                               3729                 :                : 
                               3730                 :                :         /*
                               3731                 :                :          * Create a "BLOBS" data item for the group, too. This is just a
                               3732                 :                :          * placeholder for sorting; it carries no data now.
                               3733                 :                :          */
  496 peter@eisentraut.org     3734                 :CBC          79 :         lodata = (DumpableObject *) pg_malloc(sizeof(DumpableObject));
                               3735                 :             79 :         lodata->objType = DO_LARGE_OBJECT_DATA;
                               3736                 :             79 :         lodata->catId = nilCatalogId;
                               3737                 :             79 :         AssignDumpId(lodata);
   13 tgl@sss.pgh.pa.us        3738                 :GNC          79 :         lodata->name = pg_strdup(namebuf);
  496 peter@eisentraut.org     3739                 :CBC          79 :         lodata->components |= DUMP_COMPONENT_DATA;
                               3740                 :                :         /* Set up explicit dependency from data to metadata */
   13 tgl@sss.pgh.pa.us        3741                 :GNC          79 :         lodata->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
                               3742                 :             79 :         lodata->dependencies[0] = loinfo->dobj.dumpId;
                               3743                 :             79 :         lodata->nDeps = lodata->allocDeps = 1;
                               3744                 :                :     }
                               3745                 :                : 
 6863 tgl@sss.pgh.pa.us        3746                 :CBC         131 :     PQclear(res);
  496 peter@eisentraut.org     3747                 :            131 :     destroyPQExpBuffer(loQry);
 5169 tgl@sss.pgh.pa.us        3748                 :            131 : }
                               3749                 :                : 
                               3750                 :                : /*
                               3751                 :                :  * dumpLO
                               3752                 :                :  *
                               3753                 :                :  * dump the definition (metadata) of the given large object group
                               3754                 :                :  */
                               3755                 :                : static void
  496 peter@eisentraut.org     3756                 :             79 : dumpLO(Archive *fout, const LoInfo *loinfo)
                               3757                 :                : {
 5161 bruce@momjian.us         3758                 :             79 :     PQExpBuffer cquery = createPQExpBuffer();
                               3759                 :                : 
                               3760                 :                :     /*
                               3761                 :                :      * The "definition" is just a newline-separated list of OIDs.  We need to
                               3762                 :                :      * put something into the dropStmt too, but it can just be a comment.
                               3763                 :                :      */
   13 tgl@sss.pgh.pa.us        3764         [ +  + ]:GNC         168 :     for (int i = 0; i < loinfo->numlos; i++)
                               3765                 :             89 :         appendPQExpBuffer(cquery, "%u\n", loinfo->looids[i]);
                               3766                 :                : 
  496 peter@eisentraut.org     3767         [ +  - ]:CBC          79 :     if (loinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               3768                 :             79 :         ArchiveEntry(fout, loinfo->dobj.catId, loinfo->dobj.dumpId,
                               3769                 :             79 :                      ARCHIVE_OPTS(.tag = loinfo->dobj.name,
                               3770                 :                :                                   .owner = loinfo->rolname,
                               3771                 :                :                                   .description = "BLOB METADATA",
                               3772                 :                :                                   .section = SECTION_DATA,
                               3773                 :                :                                   .createStmt = cquery->data,
                               3774                 :                :                                   .dropStmt = "-- dummy"));
                               3775                 :                : 
                               3776                 :                :     /*
                               3777                 :                :      * Dump per-blob comments and seclabels if any.  We assume these are rare
                               3778                 :                :      * enough that it's okay to generate retail TOC entries for them.
                               3779                 :                :      */
   13 tgl@sss.pgh.pa.us        3780         [ +  + ]:GNC          79 :     if (loinfo->dobj.dump & (DUMP_COMPONENT_COMMENT |
                               3781                 :                :                              DUMP_COMPONENT_SECLABEL))
                               3782                 :                :     {
                               3783         [ +  + ]:             94 :         for (int i = 0; i < loinfo->numlos; i++)
                               3784                 :                :         {
                               3785                 :                :             CatalogId   catId;
                               3786                 :                :             char        namebuf[32];
                               3787                 :                : 
                               3788                 :                :             /* Build identifying info for this blob */
                               3789                 :             52 :             catId.tableoid = loinfo->dobj.catId.tableoid;
                               3790                 :             52 :             catId.oid = loinfo->looids[i];
                               3791                 :             52 :             snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[i]);
                               3792                 :                : 
                               3793         [ +  - ]:             52 :             if (loinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                               3794                 :             52 :                 dumpComment(fout, "LARGE OBJECT", namebuf,
                               3795                 :             52 :                             NULL, loinfo->rolname,
                               3796                 :             52 :                             catId, 0, loinfo->dobj.dumpId);
                               3797                 :                : 
                               3798         [ -  + ]:             52 :             if (loinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
   13 tgl@sss.pgh.pa.us        3799                 :UNC           0 :                 dumpSecLabel(fout, "LARGE OBJECT", namebuf,
                               3800                 :              0 :                              NULL, loinfo->rolname,
                               3801                 :              0 :                              catId, 0, loinfo->dobj.dumpId);
                               3802                 :                :         }
                               3803                 :                :     }
                               3804                 :                : 
                               3805                 :                :     /*
                               3806                 :                :      * Dump the ACLs if any (remember that all blobs in the group will have
                               3807                 :                :      * the same ACL).  If there's just one blob, dump a simple ACL entry; if
                               3808                 :                :      * there's more, make a "LARGE OBJECTS" entry that really contains only
                               3809                 :                :      * the ACL for the first blob.  _printTocEntry() will be cued by the tag
                               3810                 :                :      * string to emit a mutated version for each blob.
                               3811                 :                :      */
  496 peter@eisentraut.org     3812         [ +  + ]:CBC          79 :     if (loinfo->dobj.dump & DUMP_COMPONENT_ACL)
                               3813                 :                :     {
                               3814                 :                :         char        namebuf[32];
                               3815                 :                : 
                               3816                 :                :         /* Build identifying info for the first blob */
   13 tgl@sss.pgh.pa.us        3817                 :GNC          37 :         snprintf(namebuf, sizeof(namebuf), "%u", loinfo->looids[0]);
                               3818                 :                : 
                               3819         [ -  + ]:             37 :         if (loinfo->numlos > 1)
                               3820                 :                :         {
                               3821                 :                :             char        tagbuf[64];
                               3822                 :                : 
   13 tgl@sss.pgh.pa.us        3823                 :UNC           0 :             snprintf(tagbuf, sizeof(tagbuf), "LARGE OBJECTS %u..%u",
                               3824                 :              0 :                      loinfo->looids[0], loinfo->looids[loinfo->numlos - 1]);
                               3825                 :                : 
                               3826                 :              0 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               3827                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               3828                 :              0 :                     tagbuf, loinfo->rolname, &loinfo->dacl);
                               3829                 :                :         }
                               3830                 :                :         else
                               3831                 :                :         {
   13 tgl@sss.pgh.pa.us        3832                 :GNC          37 :             dumpACL(fout, loinfo->dobj.dumpId, InvalidDumpId,
                               3833                 :                :                     "LARGE OBJECT", namebuf, NULL, NULL,
                               3834                 :             37 :                     NULL, loinfo->rolname, &loinfo->dacl);
                               3835                 :                :         }
                               3836                 :                :     }
                               3837                 :                : 
 5169 tgl@sss.pgh.pa.us        3838                 :CBC          79 :     destroyPQExpBuffer(cquery);
 6863                          3839                 :             79 : }
                               3840                 :                : 
                               3841                 :                : /*
                               3842                 :                :  * dumpLOs:
                               3843                 :                :  *  dump the data contents of the large objects in the given group
                               3844                 :                :  */
                               3845                 :                : static int
  496 peter@eisentraut.org     3846                 :             72 : dumpLOs(Archive *fout, const void *arg)
                               3847                 :                : {
   13 tgl@sss.pgh.pa.us        3848                 :GNC          72 :     const LoInfo *loinfo = (const LoInfo *) arg;
 4441 rhaas@postgresql.org     3849                 :CBC          72 :     PGconn     *conn = GetConnection(fout);
                               3850                 :                :     char        buf[LOBBUFSIZE];
                               3851                 :                : 
   13 tgl@sss.pgh.pa.us        3852                 :GNC          72 :     pg_log_info("saving large objects \"%s\"", loinfo->dobj.name);
                               3853                 :                : 
                               3854         [ +  + ]:            152 :     for (int i = 0; i < loinfo->numlos; i++)
                               3855                 :                :     {
                               3856                 :             80 :         Oid         loOid = loinfo->looids[i];
                               3857                 :                :         int         loFd;
                               3858                 :                :         int         cnt;
                               3859                 :                : 
                               3860                 :                :         /* Open the LO */
                               3861                 :             80 :         loFd = lo_open(conn, loOid, INV_READ);
                               3862         [ -  + ]:             80 :         if (loFd == -1)
   13 tgl@sss.pgh.pa.us        3863                 :UNC           0 :             pg_fatal("could not open large object %u: %s",
                               3864                 :                :                      loOid, PQerrorMessage(conn));
                               3865                 :                : 
   13 tgl@sss.pgh.pa.us        3866                 :GNC          80 :         StartLO(fout, loOid);
                               3867                 :                : 
                               3868                 :                :         /* Now read it in chunks, sending data to archive */
                               3869                 :                :         do
                               3870                 :                :         {
                               3871                 :            122 :             cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                               3872         [ -  + ]:            122 :             if (cnt < 0)
   13 tgl@sss.pgh.pa.us        3873                 :UNC           0 :                 pg_fatal("error reading large object %u: %s",
                               3874                 :                :                          loOid, PQerrorMessage(conn));
                               3875                 :                : 
   13 tgl@sss.pgh.pa.us        3876                 :GNC         122 :             WriteData(fout, buf, cnt);
                               3877         [ +  + ]:            122 :         } while (cnt > 0);
                               3878                 :                : 
                               3879                 :             80 :         lo_close(conn, loFd);
                               3880                 :                : 
                               3881                 :             80 :         EndLO(fout, loOid);
                               3882                 :                :     }
                               3883                 :                : 
 6863 tgl@sss.pgh.pa.us        3884                 :CBC          72 :     return 1;
                               3885                 :                : }
                               3886                 :                : 
                               3887                 :                : /*
                               3888                 :                :  * getPolicies
                               3889                 :                :  *    get information about all RLS policies on dumpable tables.
                               3890                 :                :  */
                               3891                 :                : void
 3426 sfrost@snowman.net       3892                 :            155 : getPolicies(Archive *fout, TableInfo tblinfo[], int numTables)
                               3893                 :                : {
                               3894                 :                :     PQExpBuffer query;
                               3895                 :                :     PQExpBuffer tbloids;
                               3896                 :                :     PGresult   *res;
                               3897                 :                :     PolicyInfo *polinfo;
                               3898                 :                :     int         i_oid;
                               3899                 :                :     int         i_tableoid;
                               3900                 :                :     int         i_polrelid;
                               3901                 :                :     int         i_polname;
                               3902                 :                :     int         i_polcmd;
                               3903                 :                :     int         i_polpermissive;
                               3904                 :                :     int         i_polroles;
                               3905                 :                :     int         i_polqual;
                               3906                 :                :     int         i_polwithcheck;
                               3907                 :                :     int         i,
                               3908                 :                :                 j,
                               3909                 :                :                 ntups;
                               3910                 :                : 
                               3911                 :                :     /* No policies before 9.5 */
 3495                          3912         [ -  + ]:            155 :     if (fout->remoteVersion < 90500)
 3495 sfrost@snowman.net       3913                 :UBC           0 :         return;
                               3914                 :                : 
 3490 sfrost@snowman.net       3915                 :CBC         155 :     query = createPQExpBuffer();
  835 tgl@sss.pgh.pa.us        3916                 :            155 :     tbloids = createPQExpBuffer();
                               3917                 :                : 
                               3918                 :                :     /*
                               3919                 :                :      * Identify tables of interest, and check which ones have RLS enabled.
                               3920                 :                :      */
                               3921                 :            155 :     appendPQExpBufferChar(tbloids, '{');
 3495 sfrost@snowman.net       3922         [ +  + ]:          39419 :     for (i = 0; i < numTables; i++)
                               3923                 :                :     {
 3467 tgl@sss.pgh.pa.us        3924                 :          39264 :         TableInfo  *tbinfo = &tblinfo[i];
                               3925                 :                : 
                               3926                 :                :         /* Ignore row security on tables not to be dumped */
 2930 sfrost@snowman.net       3927         [ +  + ]:          39264 :         if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY))
 3495                          3928                 :          33327 :             continue;
                               3929                 :                : 
                               3930                 :                :         /* It can't have RLS or policies if it's not a table */
  835 tgl@sss.pgh.pa.us        3931         [ +  + ]:           5937 :         if (tbinfo->relkind != RELKIND_RELATION &&
                               3932         [ +  + ]:           1684 :             tbinfo->relkind != RELKIND_PARTITIONED_TABLE)
                               3933                 :           1163 :             continue;
                               3934                 :                : 
                               3935                 :                :         /* Add it to the list of table OIDs to be probed below */
                               3936         [ +  + ]:           4774 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               3937                 :           4675 :             appendPQExpBufferChar(tbloids, ',');
                               3938                 :           4774 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               3939                 :                : 
                               3940                 :                :         /* Is RLS enabled?  (That's separate from whether it has policies) */
 3490 sfrost@snowman.net       3941         [ +  + ]:           4774 :         if (tbinfo->rowsec)
                               3942                 :                :         {
  860 tgl@sss.pgh.pa.us        3943                 :             55 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               3944                 :                : 
                               3945                 :                :             /*
                               3946                 :                :              * We represent RLS being enabled on a table by creating a
                               3947                 :                :              * PolicyInfo object with null polname.
                               3948                 :                :              *
                               3949                 :                :              * Note: use tableoid 0 so that this object won't be mistaken for
                               3950                 :                :              * something that pg_depend entries apply to.
                               3951                 :                :              */
 3426 sfrost@snowman.net       3952                 :             55 :             polinfo = pg_malloc(sizeof(PolicyInfo));
                               3953                 :             55 :             polinfo->dobj.objType = DO_POLICY;
                               3954                 :             55 :             polinfo->dobj.catId.tableoid = 0;
                               3955                 :             55 :             polinfo->dobj.catId.oid = tbinfo->dobj.catId.oid;
                               3956                 :             55 :             AssignDumpId(&polinfo->dobj);
                               3957                 :             55 :             polinfo->dobj.namespace = tbinfo->dobj.namespace;
                               3958                 :             55 :             polinfo->dobj.name = pg_strdup(tbinfo->dobj.name);
                               3959                 :             55 :             polinfo->poltable = tbinfo;
                               3960                 :             55 :             polinfo->polname = NULL;
 2687                          3961                 :             55 :             polinfo->polcmd = '\0';
                               3962                 :             55 :             polinfo->polpermissive = 0;
 3426                          3963                 :             55 :             polinfo->polroles = NULL;
                               3964                 :             55 :             polinfo->polqual = NULL;
                               3965                 :             55 :             polinfo->polwithcheck = NULL;
                               3966                 :                :         }
                               3967                 :                :     }
  835 tgl@sss.pgh.pa.us        3968                 :            155 :     appendPQExpBufferChar(tbloids, '}');
                               3969                 :                : 
                               3970                 :                :     /*
                               3971                 :                :      * Now, read all RLS policies belonging to the tables of interest, and
                               3972                 :                :      * create PolicyInfo objects for them.  (Note that we must filter the
                               3973                 :                :      * results server-side not locally, because we dare not apply pg_get_expr
                               3974                 :                :      * to tables we don't have lock on.)
                               3975                 :                :      */
  957                          3976                 :            155 :     pg_log_info("reading row-level security policies");
                               3977                 :                : 
                               3978                 :            155 :     printfPQExpBuffer(query,
                               3979                 :                :                       "SELECT pol.oid, pol.tableoid, pol.polrelid, pol.polname, pol.polcmd, ");
                               3980         [ +  - ]:            155 :     if (fout->remoteVersion >= 100000)
  586 drowley@postgresql.o     3981                 :            155 :         appendPQExpBufferStr(query, "pol.polpermissive, ");
                               3982                 :                :     else
  586 drowley@postgresql.o     3983                 :UBC           0 :         appendPQExpBufferStr(query, "'t' as polpermissive, ");
  957 tgl@sss.pgh.pa.us        3984                 :CBC         155 :     appendPQExpBuffer(query,
                               3985                 :                :                       "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE "
                               3986                 :                :                       "   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, "
                               3987                 :                :                       "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid) AS polqual, "
                               3988                 :                :                       "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid) AS polwithcheck "
                               3989                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               3990                 :                :                       "JOIN pg_catalog.pg_policy pol ON (src.tbloid = pol.polrelid)",
                               3991                 :                :                       tbloids->data);
                               3992                 :                : 
                               3993                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               3994                 :                : 
                               3995                 :            155 :     ntups = PQntuples(res);
                               3996         [ +  + ]:            155 :     if (ntups > 0)
                               3997                 :                :     {
 3495 sfrost@snowman.net       3998                 :             45 :         i_oid = PQfnumber(res, "oid");
                               3999                 :             45 :         i_tableoid = PQfnumber(res, "tableoid");
  957 tgl@sss.pgh.pa.us        4000                 :             45 :         i_polrelid = PQfnumber(res, "polrelid");
 3426 sfrost@snowman.net       4001                 :             45 :         i_polname = PQfnumber(res, "polname");
                               4002                 :             45 :         i_polcmd = PQfnumber(res, "polcmd");
 2687                          4003                 :             45 :         i_polpermissive = PQfnumber(res, "polpermissive");
 3426                          4004                 :             45 :         i_polroles = PQfnumber(res, "polroles");
                               4005                 :             45 :         i_polqual = PQfnumber(res, "polqual");
                               4006                 :             45 :         i_polwithcheck = PQfnumber(res, "polwithcheck");
                               4007                 :                : 
                               4008                 :             45 :         polinfo = pg_malloc(ntups * sizeof(PolicyInfo));
                               4009                 :                : 
 3495                          4010         [ +  + ]:            330 :         for (j = 0; j < ntups; j++)
                               4011                 :                :         {
  957 tgl@sss.pgh.pa.us        4012                 :            285 :             Oid         polrelid = atooid(PQgetvalue(res, j, i_polrelid));
                               4013                 :            285 :             TableInfo  *tbinfo = findTableByOid(polrelid);
                               4014                 :                : 
  860                          4015                 :            285 :             tbinfo->dobj.components |= DUMP_COMPONENT_POLICY;
                               4016                 :                : 
 3426 sfrost@snowman.net       4017                 :            285 :             polinfo[j].dobj.objType = DO_POLICY;
                               4018                 :            285 :             polinfo[j].dobj.catId.tableoid =
 3495                          4019                 :            285 :                 atooid(PQgetvalue(res, j, i_tableoid));
 3426                          4020                 :            285 :             polinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               4021                 :            285 :             AssignDumpId(&polinfo[j].dobj);
                               4022                 :            285 :             polinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4023                 :            285 :             polinfo[j].poltable = tbinfo;
                               4024                 :            285 :             polinfo[j].polname = pg_strdup(PQgetvalue(res, j, i_polname));
                               4025                 :            285 :             polinfo[j].dobj.name = pg_strdup(polinfo[j].polname);
                               4026                 :                : 
 2687                          4027                 :            285 :             polinfo[j].polcmd = *(PQgetvalue(res, j, i_polcmd));
                               4028                 :            285 :             polinfo[j].polpermissive = *(PQgetvalue(res, j, i_polpermissive)) == 't';
                               4029                 :                : 
                               4030         [ +  + ]:            285 :             if (PQgetisnull(res, j, i_polroles))
                               4031                 :            125 :                 polinfo[j].polroles = NULL;
                               4032                 :                :             else
                               4033                 :            160 :                 polinfo[j].polroles = pg_strdup(PQgetvalue(res, j, i_polroles));
                               4034                 :                : 
 3426                          4035         [ +  + ]:            285 :             if (PQgetisnull(res, j, i_polqual))
                               4036                 :             40 :                 polinfo[j].polqual = NULL;
                               4037                 :                :             else
                               4038                 :            245 :                 polinfo[j].polqual = pg_strdup(PQgetvalue(res, j, i_polqual));
                               4039                 :                : 
                               4040         [ +  + ]:            285 :             if (PQgetisnull(res, j, i_polwithcheck))
                               4041                 :            150 :                 polinfo[j].polwithcheck = NULL;
                               4042                 :                :             else
                               4043                 :            135 :                 polinfo[j].polwithcheck
                               4044                 :            135 :                     = pg_strdup(PQgetvalue(res, j, i_polwithcheck));
                               4045                 :                :         }
                               4046                 :                :     }
                               4047                 :                : 
  957 tgl@sss.pgh.pa.us        4048                 :            155 :     PQclear(res);
                               4049                 :                : 
 3495 sfrost@snowman.net       4050                 :            155 :     destroyPQExpBuffer(query);
  835 tgl@sss.pgh.pa.us        4051                 :            155 :     destroyPQExpBuffer(tbloids);
                               4052                 :                : }
                               4053                 :                : 
                               4054                 :                : /*
                               4055                 :                :  * dumpPolicy
                               4056                 :                :  *    dump the definition of the given policy
                               4057                 :                :  */
                               4058                 :                : static void
 1159 peter@eisentraut.org     4059                 :            340 : dumpPolicy(Archive *fout, const PolicyInfo *polinfo)
                               4060                 :                : {
 3014 tgl@sss.pgh.pa.us        4061                 :            340 :     DumpOptions *dopt = fout->dopt;
 3426 sfrost@snowman.net       4062                 :            340 :     TableInfo  *tbinfo = polinfo->poltable;
                               4063                 :                :     PQExpBuffer query;
                               4064                 :                :     PQExpBuffer delqry;
                               4065                 :                :     PQExpBuffer polprefix;
                               4066                 :                :     char       *qtabname;
                               4067                 :                :     const char *cmd;
                               4068                 :                :     char       *tag;
                               4069                 :                : 
                               4070                 :                :     /* Do nothing in data-only dump */
 3470 alvherre@alvh.no-ip.     4071         [ +  + ]:            340 :     if (dopt->dataOnly)
 3495 sfrost@snowman.net       4072                 :             28 :         return;
                               4073                 :                : 
                               4074                 :                :     /*
                               4075                 :                :      * If polname is NULL, then this record is just indicating that ROW LEVEL
                               4076                 :                :      * SECURITY is enabled for the table. Dump as ALTER TABLE <table> ENABLE
                               4077                 :                :      * ROW LEVEL SECURITY.
                               4078                 :                :      */
 3426                          4079         [ +  + ]:            312 :     if (polinfo->polname == NULL)
                               4080                 :                :     {
 3495                          4081                 :             51 :         query = createPQExpBuffer();
                               4082                 :                : 
                               4083                 :             51 :         appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;",
 2057 tgl@sss.pgh.pa.us        4084                 :             51 :                           fmtQualifiedDumpable(tbinfo));
                               4085                 :                : 
                               4086                 :                :         /*
                               4087                 :                :          * We must emit the ROW SECURITY object's dependency on its table
                               4088                 :                :          * explicitly, because it will not match anything in pg_depend (unlike
                               4089                 :                :          * the case for other PolicyInfo objects).
                               4090                 :                :          */
  860                          4091         [ +  - ]:             51 :         if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 2930 sfrost@snowman.net       4092                 :             51 :             ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.     4093                 :             51 :                          ARCHIVE_OPTS(.tag = polinfo->dobj.name,
                               4094                 :                :                                       .namespace = polinfo->dobj.namespace->dobj.name,
                               4095                 :                :                                       .owner = tbinfo->rolname,
                               4096                 :                :                                       .description = "ROW SECURITY",
                               4097                 :                :                                       .section = SECTION_POST_DATA,
                               4098                 :                :                                       .createStmt = query->data,
                               4099                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                               4100                 :                :                                       .nDeps = 1));
                               4101                 :                : 
 3495 sfrost@snowman.net       4102                 :             51 :         destroyPQExpBuffer(query);
                               4103                 :             51 :         return;
                               4104                 :                :     }
                               4105                 :                : 
 2687                          4106         [ +  + ]:            261 :     if (polinfo->polcmd == '*')
                               4107                 :             87 :         cmd = "";
                               4108         [ +  + ]:            174 :     else if (polinfo->polcmd == 'r')
                               4109                 :             46 :         cmd = " FOR SELECT";
                               4110         [ +  + ]:            128 :     else if (polinfo->polcmd == 'a')
                               4111                 :             36 :         cmd = " FOR INSERT";
                               4112         [ +  + ]:             92 :     else if (polinfo->polcmd == 'w')
                               4113                 :             46 :         cmd = " FOR UPDATE";
                               4114         [ +  - ]:             46 :     else if (polinfo->polcmd == 'd')
                               4115                 :             46 :         cmd = " FOR DELETE";
                               4116                 :                :     else
  737 tgl@sss.pgh.pa.us        4117                 :UBC           0 :         pg_fatal("unexpected policy command type: %c",
                               4118                 :                :                  polinfo->polcmd);
                               4119                 :                : 
 3495 sfrost@snowman.net       4120                 :CBC         261 :     query = createPQExpBuffer();
                               4121                 :            261 :     delqry = createPQExpBuffer();
 1518 tgl@sss.pgh.pa.us        4122                 :            261 :     polprefix = createPQExpBuffer();
                               4123                 :                : 
                               4124                 :            261 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                               4125                 :                : 
 3368                          4126                 :            261 :     appendPQExpBuffer(query, "CREATE POLICY %s", fmtId(polinfo->polname));
                               4127                 :                : 
 2239                          4128                 :            261 :     appendPQExpBuffer(query, " ON %s%s%s", fmtQualifiedDumpable(tbinfo),
 2687 sfrost@snowman.net       4129         [ +  + ]:            261 :                       !polinfo->polpermissive ? " AS RESTRICTIVE" : "", cmd);
                               4130                 :                : 
 3426                          4131         [ +  + ]:            261 :     if (polinfo->polroles != NULL)
                               4132                 :            144 :         appendPQExpBuffer(query, " TO %s", polinfo->polroles);
                               4133                 :                : 
                               4134         [ +  + ]:            261 :     if (polinfo->polqual != NULL)
 3184 mail@joeconway.com       4135                 :            225 :         appendPQExpBuffer(query, " USING (%s)", polinfo->polqual);
                               4136                 :                : 
 3426 sfrost@snowman.net       4137         [ +  + ]:            261 :     if (polinfo->polwithcheck != NULL)
 3184 mail@joeconway.com       4138                 :            123 :         appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck);
                               4139                 :                : 
 1746 drowley@postgresql.o     4140                 :            261 :     appendPQExpBufferStr(query, ";\n");
                               4141                 :                : 
 3368 tgl@sss.pgh.pa.us        4142                 :            261 :     appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname));
 2239                          4143                 :            261 :     appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo));
                               4144                 :                : 
 1518                          4145                 :            261 :     appendPQExpBuffer(polprefix, "POLICY %s ON",
                               4146                 :            261 :                       fmtId(polinfo->polname));
                               4147                 :                : 
 2971 peter_e@gmx.net          4148                 :            261 :     tag = psprintf("%s %s", tbinfo->dobj.name, polinfo->dobj.name);
                               4149                 :                : 
  860 tgl@sss.pgh.pa.us        4150         [ +  - ]:            261 :     if (polinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 2930 sfrost@snowman.net       4151                 :            261 :         ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.     4152                 :            261 :                      ARCHIVE_OPTS(.tag = tag,
                               4153                 :                :                                   .namespace = polinfo->dobj.namespace->dobj.name,
                               4154                 :                :                                   .owner = tbinfo->rolname,
                               4155                 :                :                                   .description = "POLICY",
                               4156                 :                :                                   .section = SECTION_POST_DATA,
                               4157                 :                :                                   .createStmt = query->data,
                               4158                 :                :                                   .dropStmt = delqry->data));
                               4159                 :                : 
 1518 tgl@sss.pgh.pa.us        4160         [ -  + ]:            261 :     if (polinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 1518 tgl@sss.pgh.pa.us        4161                 :UBC           0 :         dumpComment(fout, polprefix->data, qtabname,
                               4162                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                               4163                 :              0 :                     polinfo->dobj.catId, 0, polinfo->dobj.dumpId);
                               4164                 :                : 
 2971 peter_e@gmx.net          4165                 :CBC         261 :     free(tag);
 3495 sfrost@snowman.net       4166                 :            261 :     destroyPQExpBuffer(query);
                               4167                 :            261 :     destroyPQExpBuffer(delqry);
 1518 tgl@sss.pgh.pa.us        4168                 :            261 :     destroyPQExpBuffer(polprefix);
                               4169                 :            261 :     free(qtabname);
                               4170                 :                : }
                               4171                 :                : 
                               4172                 :                : /*
                               4173                 :                :  * getPublications
                               4174                 :                :  *    get information about publications
                               4175                 :                :  */
                               4176                 :                : PublicationInfo *
 1186                          4177                 :            155 : getPublications(Archive *fout, int *numPublications)
                               4178                 :                : {
 2529 peter_e@gmx.net          4179                 :            155 :     DumpOptions *dopt = fout->dopt;
                               4180                 :                :     PQExpBuffer query;
                               4181                 :                :     PGresult   *res;
                               4182                 :                :     PublicationInfo *pubinfo;
                               4183                 :                :     int         i_tableoid;
                               4184                 :                :     int         i_oid;
                               4185                 :                :     int         i_pubname;
                               4186                 :                :     int         i_pubowner;
                               4187                 :                :     int         i_puballtables;
                               4188                 :                :     int         i_pubinsert;
                               4189                 :                :     int         i_pubupdate;
                               4190                 :                :     int         i_pubdelete;
                               4191                 :                :     int         i_pubtruncate;
                               4192                 :                :     int         i_pubviaroot;
                               4193                 :                :     int         i,
                               4194                 :                :                 ntups;
                               4195                 :                : 
                               4196   [ +  -  -  + ]:            155 :     if (dopt->no_publications || fout->remoteVersion < 100000)
                               4197                 :                :     {
 1186 tgl@sss.pgh.pa.us        4198                 :UBC           0 :         *numPublications = 0;
                               4199                 :              0 :         return NULL;
                               4200                 :                :     }
                               4201                 :                : 
 2642 peter_e@gmx.net          4202                 :CBC         155 :     query = createPQExpBuffer();
                               4203                 :                : 
                               4204                 :            155 :     resetPQExpBuffer(query);
                               4205                 :                : 
                               4206                 :                :     /* Get the publications. */
  738 tomas.vondra@postgre     4207         [ +  - ]:            155 :     if (fout->remoteVersion >= 130000)
  586 drowley@postgresql.o     4208                 :            155 :         appendPQExpBufferStr(query,
                               4209                 :                :                              "SELECT p.tableoid, p.oid, p.pubname, "
                               4210                 :                :                              "p.pubowner, "
                               4211                 :                :                              "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, p.pubviaroot "
                               4212                 :                :                              "FROM pg_publication p");
 1467 peter@eisentraut.org     4213         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 110000)
  586 drowley@postgresql.o     4214                 :              0 :         appendPQExpBufferStr(query,
                               4215                 :                :                              "SELECT p.tableoid, p.oid, p.pubname, "
                               4216                 :                :                              "p.pubowner, "
                               4217                 :                :                              "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, p.pubtruncate, false AS pubviaroot "
                               4218                 :                :                              "FROM pg_publication p");
                               4219                 :                :     else
                               4220                 :              0 :         appendPQExpBufferStr(query,
                               4221                 :                :                              "SELECT p.tableoid, p.oid, p.pubname, "
                               4222                 :                :                              "p.pubowner, "
                               4223                 :                :                              "p.puballtables, p.pubinsert, p.pubupdate, p.pubdelete, false AS pubtruncate, false AS pubviaroot "
                               4224                 :                :                              "FROM pg_publication p");
                               4225                 :                : 
 2642 peter_e@gmx.net          4226                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4227                 :                : 
                               4228                 :            155 :     ntups = PQntuples(res);
                               4229                 :                : 
                               4230                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               4231                 :            155 :     i_oid = PQfnumber(res, "oid");
                               4232                 :            155 :     i_pubname = PQfnumber(res, "pubname");
  835 tgl@sss.pgh.pa.us        4233                 :            155 :     i_pubowner = PQfnumber(res, "pubowner");
 2642 peter_e@gmx.net          4234                 :            155 :     i_puballtables = PQfnumber(res, "puballtables");
                               4235                 :            155 :     i_pubinsert = PQfnumber(res, "pubinsert");
                               4236                 :            155 :     i_pubupdate = PQfnumber(res, "pubupdate");
                               4237                 :            155 :     i_pubdelete = PQfnumber(res, "pubdelete");
 2199                          4238                 :            155 :     i_pubtruncate = PQfnumber(res, "pubtruncate");
 1467 peter@eisentraut.org     4239                 :            155 :     i_pubviaroot = PQfnumber(res, "pubviaroot");
                               4240                 :                : 
 2642 peter_e@gmx.net          4241                 :            155 :     pubinfo = pg_malloc(ntups * sizeof(PublicationInfo));
                               4242                 :                : 
                               4243         [ +  + ]:            340 :     for (i = 0; i < ntups; i++)
                               4244                 :                :     {
                               4245                 :            185 :         pubinfo[i].dobj.objType = DO_PUBLICATION;
                               4246                 :            185 :         pubinfo[i].dobj.catId.tableoid =
                               4247                 :            185 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4248                 :            185 :         pubinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4249                 :            185 :         AssignDumpId(&pubinfo[i].dobj);
                               4250                 :            185 :         pubinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_pubname));
  835 tgl@sss.pgh.pa.us        4251                 :            185 :         pubinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_pubowner));
 2642 peter_e@gmx.net          4252                 :            185 :         pubinfo[i].puballtables =
                               4253                 :            185 :             (strcmp(PQgetvalue(res, i, i_puballtables), "t") == 0);
                               4254                 :            185 :         pubinfo[i].pubinsert =
                               4255                 :            185 :             (strcmp(PQgetvalue(res, i, i_pubinsert), "t") == 0);
                               4256                 :            185 :         pubinfo[i].pubupdate =
                               4257                 :            185 :             (strcmp(PQgetvalue(res, i, i_pubupdate), "t") == 0);
                               4258                 :            185 :         pubinfo[i].pubdelete =
                               4259                 :            185 :             (strcmp(PQgetvalue(res, i, i_pubdelete), "t") == 0);
 2199                          4260                 :            185 :         pubinfo[i].pubtruncate =
                               4261                 :            185 :             (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0);
 1467 peter@eisentraut.org     4262                 :            185 :         pubinfo[i].pubviaroot =
                               4263                 :            185 :             (strcmp(PQgetvalue(res, i, i_pubviaroot), "t") == 0);
                               4264                 :                : 
                               4265                 :                :         /* Decide whether we want to dump it */
 2581 peter_e@gmx.net          4266                 :            185 :         selectDumpableObject(&(pubinfo[i].dobj), fout);
                               4267                 :                :     }
 2642                          4268                 :            155 :     PQclear(res);
                               4269                 :                : 
                               4270                 :            155 :     destroyPQExpBuffer(query);
                               4271                 :                : 
 1186 tgl@sss.pgh.pa.us        4272                 :            155 :     *numPublications = ntups;
                               4273                 :            155 :     return pubinfo;
                               4274                 :                : }
                               4275                 :                : 
                               4276                 :                : /*
                               4277                 :                :  * dumpPublication
                               4278                 :                :  *    dump the definition of the given publication
                               4279                 :                :  */
                               4280                 :                : static void
 1159 peter@eisentraut.org     4281                 :            153 : dumpPublication(Archive *fout, const PublicationInfo *pubinfo)
                               4282                 :                : {
  836 tgl@sss.pgh.pa.us        4283                 :            153 :     DumpOptions *dopt = fout->dopt;
                               4284                 :                :     PQExpBuffer delq;
                               4285                 :                :     PQExpBuffer query;
                               4286                 :                :     char       *qpubname;
 2529 peter_e@gmx.net          4287                 :            153 :     bool        first = true;
                               4288                 :                : 
                               4289                 :                :     /* Do nothing in data-only dump */
  836 tgl@sss.pgh.pa.us        4290         [ +  + ]:            153 :     if (dopt->dataOnly)
                               4291                 :             12 :         return;
                               4292                 :                : 
 2642 peter_e@gmx.net          4293                 :            141 :     delq = createPQExpBuffer();
                               4294                 :            141 :     query = createPQExpBuffer();
                               4295                 :                : 
 2239 tgl@sss.pgh.pa.us        4296                 :            141 :     qpubname = pg_strdup(fmtId(pubinfo->dobj.name));
                               4297                 :                : 
 2642 peter_e@gmx.net          4298                 :            141 :     appendPQExpBuffer(delq, "DROP PUBLICATION %s;\n",
                               4299                 :                :                       qpubname);
                               4300                 :                : 
                               4301                 :            141 :     appendPQExpBuffer(query, "CREATE PUBLICATION %s",
                               4302                 :                :                       qpubname);
                               4303                 :                : 
                               4304         [ +  + ]:            141 :     if (pubinfo->puballtables)
                               4305                 :             36 :         appendPQExpBufferStr(query, " FOR ALL TABLES");
                               4306                 :                : 
 2529                          4307                 :            141 :     appendPQExpBufferStr(query, " WITH (publish = '");
 2642                          4308         [ +  + ]:            141 :     if (pubinfo->pubinsert)
                               4309                 :                :     {
 2529                          4310                 :            106 :         appendPQExpBufferStr(query, "insert");
                               4311                 :            106 :         first = false;
                               4312                 :                :     }
                               4313                 :                : 
 2642                          4314         [ +  + ]:            141 :     if (pubinfo->pubupdate)
                               4315                 :                :     {
 2526 tgl@sss.pgh.pa.us        4316         [ +  - ]:            106 :         if (!first)
                               4317                 :            106 :             appendPQExpBufferStr(query, ", ");
                               4318                 :                : 
 2529 peter_e@gmx.net          4319                 :            106 :         appendPQExpBufferStr(query, "update");
                               4320                 :            106 :         first = false;
                               4321                 :                :     }
                               4322                 :                : 
 2642                          4323         [ +  + ]:            141 :     if (pubinfo->pubdelete)
                               4324                 :                :     {
 2526 tgl@sss.pgh.pa.us        4325         [ +  - ]:            106 :         if (!first)
                               4326                 :            106 :             appendPQExpBufferStr(query, ", ");
                               4327                 :                : 
 2529 peter_e@gmx.net          4328                 :            106 :         appendPQExpBufferStr(query, "delete");
                               4329                 :            106 :         first = false;
                               4330                 :                :     }
                               4331                 :                : 
 2199                          4332         [ +  + ]:            141 :     if (pubinfo->pubtruncate)
                               4333                 :                :     {
                               4334         [ +  - ]:            106 :         if (!first)
                               4335                 :            106 :             appendPQExpBufferStr(query, ", ");
                               4336                 :                : 
                               4337                 :            106 :         appendPQExpBufferStr(query, "truncate");
                               4338                 :            106 :         first = false;
                               4339                 :                :     }
                               4340                 :                : 
  586 drowley@postgresql.o     4341                 :            141 :     appendPQExpBufferChar(query, '\'');
                               4342                 :                : 
 1467 peter@eisentraut.org     4343         [ -  + ]:            141 :     if (pubinfo->pubviaroot)
 1467 peter@eisentraut.org     4344                 :UBC           0 :         appendPQExpBufferStr(query, ", publish_via_partition_root = true");
                               4345                 :                : 
 1467 peter@eisentraut.org     4346                 :CBC         141 :     appendPQExpBufferStr(query, ");\n");
                               4347                 :                : 
  860 tgl@sss.pgh.pa.us        4348         [ +  - ]:            141 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4349                 :            141 :         ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
                               4350                 :            141 :                      ARCHIVE_OPTS(.tag = pubinfo->dobj.name,
                               4351                 :                :                                   .owner = pubinfo->rolname,
                               4352                 :                :                                   .description = "PUBLICATION",
                               4353                 :                :                                   .section = SECTION_POST_DATA,
                               4354                 :                :                                   .createStmt = query->data,
                               4355                 :                :                                   .dropStmt = delq->data));
                               4356                 :                : 
 2558 peter_e@gmx.net          4357         [ +  + ]:            141 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us        4358                 :             35 :         dumpComment(fout, "PUBLICATION", qpubname,
 2558 peter_e@gmx.net          4359                 :             35 :                     NULL, pubinfo->rolname,
                               4360                 :             35 :                     pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4361                 :                : 
                               4362         [ -  + ]:            141 :     if (pubinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us        4363                 :UBC           0 :         dumpSecLabel(fout, "PUBLICATION", qpubname,
 2558 peter_e@gmx.net          4364                 :              0 :                      NULL, pubinfo->rolname,
                               4365                 :              0 :                      pubinfo->dobj.catId, 0, pubinfo->dobj.dumpId);
                               4366                 :                : 
 2642 peter_e@gmx.net          4367                 :CBC         141 :     destroyPQExpBuffer(delq);
                               4368                 :            141 :     destroyPQExpBuffer(query);
 2239 tgl@sss.pgh.pa.us        4369                 :            141 :     free(qpubname);
                               4370                 :                : }
                               4371                 :                : 
                               4372                 :                : /*
                               4373                 :                :  * getPublicationNamespaces
                               4374                 :                :  *    get information about publication membership for dumpable schemas.
                               4375                 :                :  */
                               4376                 :                : void
  900 akapila@postgresql.o     4377                 :            155 : getPublicationNamespaces(Archive *fout)
                               4378                 :                : {
                               4379                 :                :     PQExpBuffer query;
                               4380                 :                :     PGresult   *res;
                               4381                 :                :     PublicationSchemaInfo *pubsinfo;
                               4382                 :            155 :     DumpOptions *dopt = fout->dopt;
                               4383                 :                :     int         i_tableoid;
                               4384                 :                :     int         i_oid;
                               4385                 :                :     int         i_pnpubid;
                               4386                 :                :     int         i_pnnspid;
                               4387                 :                :     int         i,
                               4388                 :                :                 j,
                               4389                 :                :                 ntups;
                               4390                 :                : 
                               4391   [ +  -  -  + ]:            155 :     if (dopt->no_publications || fout->remoteVersion < 150000)
  900 akapila@postgresql.o     4392                 :UBC           0 :         return;
                               4393                 :                : 
  900 akapila@postgresql.o     4394                 :CBC         155 :     query = createPQExpBuffer();
                               4395                 :                : 
                               4396                 :                :     /* Collect all publication membership info. */
                               4397                 :            155 :     appendPQExpBufferStr(query,
                               4398                 :                :                          "SELECT tableoid, oid, pnpubid, pnnspid "
                               4399                 :                :                          "FROM pg_catalog.pg_publication_namespace");
                               4400                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4401                 :                : 
                               4402                 :            155 :     ntups = PQntuples(res);
                               4403                 :                : 
                               4404                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               4405                 :            155 :     i_oid = PQfnumber(res, "oid");
                               4406                 :            155 :     i_pnpubid = PQfnumber(res, "pnpubid");
                               4407                 :            155 :     i_pnnspid = PQfnumber(res, "pnnspid");
                               4408                 :                : 
                               4409                 :                :     /* this allocation may be more than we need */
                               4410                 :            155 :     pubsinfo = pg_malloc(ntups * sizeof(PublicationSchemaInfo));
                               4411                 :            155 :     j = 0;
                               4412                 :                : 
                               4413         [ +  + ]:            247 :     for (i = 0; i < ntups; i++)
                               4414                 :                :     {
                               4415                 :             92 :         Oid         pnpubid = atooid(PQgetvalue(res, i, i_pnpubid));
                               4416                 :             92 :         Oid         pnnspid = atooid(PQgetvalue(res, i, i_pnnspid));
                               4417                 :                :         PublicationInfo *pubinfo;
                               4418                 :                :         NamespaceInfo *nspinfo;
                               4419                 :                : 
                               4420                 :                :         /*
                               4421                 :                :          * Ignore any entries for which we aren't interested in either the
                               4422                 :                :          * publication or the rel.
                               4423                 :                :          */
                               4424                 :             92 :         pubinfo = findPublicationByOid(pnpubid);
                               4425         [ -  + ]:             92 :         if (pubinfo == NULL)
  900 akapila@postgresql.o     4426                 :UBC           0 :             continue;
  900 akapila@postgresql.o     4427                 :CBC          92 :         nspinfo = findNamespaceByOid(pnnspid);
                               4428         [ -  + ]:             92 :         if (nspinfo == NULL)
  900 akapila@postgresql.o     4429                 :UBC           0 :             continue;
                               4430                 :                : 
                               4431                 :                :         /*
                               4432                 :                :          * We always dump publication namespaces unless the corresponding
                               4433                 :                :          * namespace is excluded from the dump.
                               4434                 :                :          */
  900 akapila@postgresql.o     4435         [ +  + ]:CBC          92 :         if (nspinfo->dobj.dump == DUMP_COMPONENT_NONE)
                               4436                 :             15 :             continue;
                               4437                 :                : 
                               4438                 :                :         /* OK, make a DumpableObject for this relationship */
  887                          4439                 :             77 :         pubsinfo[j].dobj.objType = DO_PUBLICATION_TABLE_IN_SCHEMA;
  900                          4440                 :             77 :         pubsinfo[j].dobj.catId.tableoid =
                               4441                 :             77 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4442                 :             77 :         pubsinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4443                 :             77 :         AssignDumpId(&pubsinfo[j].dobj);
                               4444                 :             77 :         pubsinfo[j].dobj.namespace = nspinfo->dobj.namespace;
                               4445                 :             77 :         pubsinfo[j].dobj.name = nspinfo->dobj.name;
                               4446                 :             77 :         pubsinfo[j].publication = pubinfo;
                               4447                 :             77 :         pubsinfo[j].pubschema = nspinfo;
                               4448                 :                : 
                               4449                 :                :         /* Decide whether we want to dump it */
                               4450                 :             77 :         selectDumpablePublicationObject(&(pubsinfo[j].dobj), fout);
                               4451                 :                : 
                               4452                 :             77 :         j++;
                               4453                 :                :     }
                               4454                 :                : 
                               4455                 :            155 :     PQclear(res);
                               4456                 :            155 :     destroyPQExpBuffer(query);
                               4457                 :                : }
                               4458                 :                : 
                               4459                 :                : /*
                               4460                 :                :  * getPublicationTables
                               4461                 :                :  *    get information about publication membership for dumpable tables.
                               4462                 :                :  */
                               4463                 :                : void
 2642 peter_e@gmx.net          4464                 :            155 : getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables)
                               4465                 :                : {
                               4466                 :                :     PQExpBuffer query;
                               4467                 :                :     PGresult   *res;
                               4468                 :                :     PublicationRelInfo *pubrinfo;
 2028 michael@paquier.xyz      4469                 :            155 :     DumpOptions *dopt = fout->dopt;
                               4470                 :                :     int         i_tableoid;
                               4471                 :                :     int         i_oid;
                               4472                 :                :     int         i_prpubid;
                               4473                 :                :     int         i_prrelid;
                               4474                 :                :     int         i_prrelqual;
                               4475                 :                :     int         i_prattrs;
                               4476                 :                :     int         i,
                               4477                 :                :                 j,
                               4478                 :                :                 ntups;
                               4479                 :                : 
                               4480   [ +  -  -  + ]:            155 :     if (dopt->no_publications || fout->remoteVersion < 100000)
 2642 peter_e@gmx.net          4481                 :UBC           0 :         return;
                               4482                 :                : 
 2642 peter_e@gmx.net          4483                 :CBC         155 :     query = createPQExpBuffer();
                               4484                 :                : 
                               4485                 :                :     /* Collect all publication membership info. */
  782 akapila@postgresql.o     4486         [ +  - ]:            155 :     if (fout->remoteVersion >= 150000)
                               4487                 :            155 :         appendPQExpBufferStr(query,
                               4488                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4489                 :                :                              "pg_catalog.pg_get_expr(prqual, prrelid) AS prrelqual, "
                               4490                 :                :                              "(CASE\n"
                               4491                 :                :                              "  WHEN pr.prattrs IS NOT NULL THEN\n"
                               4492                 :                :                              "    (SELECT array_agg(attname)\n"
                               4493                 :                :                              "       FROM\n"
                               4494                 :                :                              "         pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
                               4495                 :                :                              "         pg_catalog.pg_attribute\n"
                               4496                 :                :                              "      WHERE attrelid = pr.prrelid AND attnum = prattrs[s])\n"
                               4497                 :                :                              "  ELSE NULL END) prattrs "
                               4498                 :                :                              "FROM pg_catalog.pg_publication_rel pr");
                               4499                 :                :     else
  782 akapila@postgresql.o     4500                 :UBC           0 :         appendPQExpBufferStr(query,
                               4501                 :                :                              "SELECT tableoid, oid, prpubid, prrelid, "
                               4502                 :                :                              "NULL AS prrelqual, NULL AS prattrs "
                               4503                 :                :                              "FROM pg_catalog.pg_publication_rel");
 1186 tgl@sss.pgh.pa.us        4504                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4505                 :                : 
                               4506                 :            155 :     ntups = PQntuples(res);
                               4507                 :                : 
                               4508                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               4509                 :            155 :     i_oid = PQfnumber(res, "oid");
                               4510                 :            155 :     i_prpubid = PQfnumber(res, "prpubid");
                               4511                 :            155 :     i_prrelid = PQfnumber(res, "prrelid");
  782 akapila@postgresql.o     4512                 :            155 :     i_prrelqual = PQfnumber(res, "prrelqual");
  750 tomas.vondra@postgre     4513                 :            155 :     i_prattrs = PQfnumber(res, "prattrs");
                               4514                 :                : 
                               4515                 :                :     /* this allocation may be more than we need */
 1186 tgl@sss.pgh.pa.us        4516                 :            155 :     pubrinfo = pg_malloc(ntups * sizeof(PublicationRelInfo));
                               4517                 :            155 :     j = 0;
                               4518                 :                : 
                               4519         [ +  + ]:            477 :     for (i = 0; i < ntups; i++)
                               4520                 :                :     {
                               4521                 :            322 :         Oid         prpubid = atooid(PQgetvalue(res, i, i_prpubid));
                               4522                 :            322 :         Oid         prrelid = atooid(PQgetvalue(res, i, i_prrelid));
                               4523                 :                :         PublicationInfo *pubinfo;
                               4524                 :                :         TableInfo  *tbinfo;
                               4525                 :                : 
                               4526                 :                :         /*
                               4527                 :                :          * Ignore any entries for which we aren't interested in either the
                               4528                 :                :          * publication or the rel.
                               4529                 :                :          */
                               4530                 :            322 :         pubinfo = findPublicationByOid(prpubid);
                               4531         [ -  + ]:            322 :         if (pubinfo == NULL)
 1186 tgl@sss.pgh.pa.us        4532                 :UBC           0 :             continue;
 1186 tgl@sss.pgh.pa.us        4533                 :CBC         322 :         tbinfo = findTableByOid(prrelid);
                               4534         [ -  + ]:            322 :         if (tbinfo == NULL)
 2642 peter_e@gmx.net          4535                 :UBC           0 :             continue;
                               4536                 :                : 
                               4537                 :                :         /*
                               4538                 :                :          * Ignore publication membership of tables whose definitions are not
                               4539                 :                :          * to be dumped.
                               4540                 :                :          */
 2642 peter_e@gmx.net          4541         [ +  + ]:CBC         322 :         if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
                               4542                 :             46 :             continue;
                               4543                 :                : 
                               4544                 :                :         /* OK, make a DumpableObject for this relationship */
 1186 tgl@sss.pgh.pa.us        4545                 :            276 :         pubrinfo[j].dobj.objType = DO_PUBLICATION_REL;
                               4546                 :            276 :         pubrinfo[j].dobj.catId.tableoid =
                               4547                 :            276 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4548                 :            276 :         pubrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4549                 :            276 :         AssignDumpId(&pubrinfo[j].dobj);
                               4550                 :            276 :         pubrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               4551                 :            276 :         pubrinfo[j].dobj.name = tbinfo->dobj.name;
                               4552                 :            276 :         pubrinfo[j].publication = pubinfo;
                               4553                 :            276 :         pubrinfo[j].pubtable = tbinfo;
  782 akapila@postgresql.o     4554         [ +  + ]:            276 :         if (PQgetisnull(res, i, i_prrelqual))
                               4555                 :            158 :             pubrinfo[j].pubrelqual = NULL;
                               4556                 :                :         else
                               4557                 :            118 :             pubrinfo[j].pubrelqual = pg_strdup(PQgetvalue(res, i, i_prrelqual));
                               4558                 :                : 
  750 tomas.vondra@postgre     4559         [ +  + ]:            276 :         if (!PQgetisnull(res, i, i_prattrs))
                               4560                 :                :         {
                               4561                 :                :             char      **attnames;
                               4562                 :                :             int         nattnames;
                               4563                 :                :             PQExpBuffer attribs;
                               4564                 :                : 
                               4565         [ -  + ]:             78 :             if (!parsePGArray(PQgetvalue(res, i, i_prattrs),
                               4566                 :                :                               &attnames, &nattnames))
  737 tgl@sss.pgh.pa.us        4567                 :UBC           0 :                 pg_fatal("could not parse %s array", "prattrs");
  750 tomas.vondra@postgre     4568                 :CBC          78 :             attribs = createPQExpBuffer();
                               4569         [ +  + ]:            234 :             for (int k = 0; k < nattnames; k++)
                               4570                 :                :             {
                               4571         [ +  + ]:            156 :                 if (k > 0)
                               4572                 :             78 :                     appendPQExpBufferStr(attribs, ", ");
                               4573                 :                : 
                               4574                 :            156 :                 appendPQExpBufferStr(attribs, fmtId(attnames[k]));
                               4575                 :                :             }
                               4576                 :             78 :             pubrinfo[j].pubrattrs = attribs->data;
                               4577                 :                :         }
                               4578                 :                :         else
                               4579                 :            198 :             pubrinfo[j].pubrattrs = NULL;
                               4580                 :                : 
                               4581                 :                :         /* Decide whether we want to dump it */
  900 akapila@postgresql.o     4582                 :            276 :         selectDumpablePublicationObject(&(pubrinfo[j].dobj), fout);
                               4583                 :                : 
 1186 tgl@sss.pgh.pa.us        4584                 :            276 :         j++;
                               4585                 :                :     }
                               4586                 :                : 
                               4587                 :            155 :     PQclear(res);
 2642 peter_e@gmx.net          4588                 :            155 :     destroyPQExpBuffer(query);
                               4589                 :                : }
                               4590                 :                : 
                               4591                 :                : /*
                               4592                 :                :  * dumpPublicationNamespace
                               4593                 :                :  *    dump the definition of the given publication schema mapping.
                               4594                 :                :  */
                               4595                 :                : static void
  900 akapila@postgresql.o     4596                 :             75 : dumpPublicationNamespace(Archive *fout, const PublicationSchemaInfo *pubsinfo)
                               4597                 :                : {
  836 tgl@sss.pgh.pa.us        4598                 :             75 :     DumpOptions *dopt = fout->dopt;
  900 akapila@postgresql.o     4599                 :             75 :     NamespaceInfo *schemainfo = pubsinfo->pubschema;
                               4600                 :             75 :     PublicationInfo *pubinfo = pubsinfo->publication;
                               4601                 :                :     PQExpBuffer query;
                               4602                 :                :     char       *tag;
                               4603                 :                : 
                               4604                 :                :     /* Do nothing in data-only dump */
  836 tgl@sss.pgh.pa.us        4605         [ +  + ]:             75 :     if (dopt->dataOnly)
  900 akapila@postgresql.o     4606                 :              6 :         return;
                               4607                 :                : 
                               4608                 :             69 :     tag = psprintf("%s %s", pubinfo->dobj.name, schemainfo->dobj.name);
                               4609                 :                : 
                               4610                 :             69 :     query = createPQExpBuffer();
                               4611                 :                : 
                               4612                 :             69 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ", fmtId(pubinfo->dobj.name));
  570 alvherre@alvh.no-ip.     4613                 :             69 :     appendPQExpBuffer(query, "ADD TABLES IN SCHEMA %s;\n", fmtId(schemainfo->dobj.name));
                               4614                 :                : 
                               4615                 :                :     /*
                               4616                 :                :      * There is no point in creating drop query as the drop is done by schema
                               4617                 :                :      * drop.
                               4618                 :                :      */
  836 tgl@sss.pgh.pa.us        4619         [ +  - ]:             69 :     if (pubsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4620                 :             69 :         ArchiveEntry(fout, pubsinfo->dobj.catId, pubsinfo->dobj.dumpId,
                               4621                 :             69 :                      ARCHIVE_OPTS(.tag = tag,
                               4622                 :                :                                   .namespace = schemainfo->dobj.name,
                               4623                 :                :                                   .owner = pubinfo->rolname,
                               4624                 :                :                                   .description = "PUBLICATION TABLES IN SCHEMA",
                               4625                 :                :                                   .section = SECTION_POST_DATA,
                               4626                 :                :                                   .createStmt = query->data));
                               4627                 :                : 
                               4628                 :                :     /* These objects can't currently have comments or seclabels */
                               4629                 :                : 
  900 akapila@postgresql.o     4630                 :             69 :     free(tag);
                               4631                 :             69 :     destroyPQExpBuffer(query);
                               4632                 :                : }
                               4633                 :                : 
                               4634                 :                : /*
                               4635                 :                :  * dumpPublicationTable
                               4636                 :                :  *    dump the definition of the given publication table mapping
                               4637                 :                :  */
                               4638                 :                : static void
 1159 peter@eisentraut.org     4639                 :            256 : dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo)
                               4640                 :                : {
  836 tgl@sss.pgh.pa.us        4641                 :            256 :     DumpOptions *dopt = fout->dopt;
 1186                          4642                 :            256 :     PublicationInfo *pubinfo = pubrinfo->publication;
 2642 peter_e@gmx.net          4643                 :            256 :     TableInfo  *tbinfo = pubrinfo->pubtable;
                               4644                 :                :     PQExpBuffer query;
                               4645                 :                :     char       *tag;
                               4646                 :                : 
                               4647                 :                :     /* Do nothing in data-only dump */
  836 tgl@sss.pgh.pa.us        4648         [ +  + ]:            256 :     if (dopt->dataOnly)
                               4649                 :             21 :         return;
                               4650                 :                : 
 1186                          4651                 :            235 :     tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name);
                               4652                 :                : 
 2642 peter_e@gmx.net          4653                 :            235 :     query = createPQExpBuffer();
                               4654                 :                : 
  738 tomas.vondra@postgre     4655                 :            235 :     appendPQExpBuffer(query, "ALTER PUBLICATION %s ADD TABLE ONLY",
                               4656                 :            235 :                       fmtId(pubinfo->dobj.name));
  782 akapila@postgresql.o     4657                 :            235 :     appendPQExpBuffer(query, " %s",
 2239 tgl@sss.pgh.pa.us        4658                 :            235 :                       fmtQualifiedDumpable(tbinfo));
                               4659                 :                : 
  750 tomas.vondra@postgre     4660         [ +  + ]:            235 :     if (pubrinfo->pubrattrs)
                               4661                 :             68 :         appendPQExpBuffer(query, " (%s)", pubrinfo->pubrattrs);
                               4662                 :                : 
  782 akapila@postgresql.o     4663         [ +  + ]:            235 :     if (pubrinfo->pubrelqual)
                               4664                 :                :     {
                               4665                 :                :         /*
                               4666                 :                :          * It's necessary to add parentheses around the expression because
                               4667                 :                :          * pg_get_expr won't supply the parentheses for things like WHERE
                               4668                 :                :          * TRUE.
                               4669                 :                :          */
                               4670                 :            101 :         appendPQExpBuffer(query, " WHERE (%s)", pubrinfo->pubrelqual);
                               4671                 :                :     }
                               4672                 :            235 :     appendPQExpBufferStr(query, ";\n");
                               4673                 :                : 
                               4674                 :                :     /*
                               4675                 :                :      * There is no point in creating a drop query as the drop is done by table
                               4676                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               4677                 :                :      * Although this object doesn't really have ownership as such, set the
                               4678                 :                :      * owner field anyway to ensure that the command is run by the correct
                               4679                 :                :      * role at restore time.
                               4680                 :                :      */
  860 tgl@sss.pgh.pa.us        4681         [ +  - ]:            235 :     if (pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               4682                 :            235 :         ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId,
                               4683                 :            235 :                      ARCHIVE_OPTS(.tag = tag,
                               4684                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                               4685                 :                :                                   .owner = pubinfo->rolname,
                               4686                 :                :                                   .description = "PUBLICATION TABLE",
                               4687                 :                :                                   .section = SECTION_POST_DATA,
                               4688                 :                :                                   .createStmt = query->data));
                               4689                 :                : 
                               4690                 :                :     /* These objects can't currently have comments or seclabels */
                               4691                 :                : 
 2642 peter_e@gmx.net          4692                 :            235 :     free(tag);
                               4693                 :            235 :     destroyPQExpBuffer(query);
                               4694                 :                : }
                               4695                 :                : 
                               4696                 :                : /*
                               4697                 :                :  * Is the currently connected user a superuser?
                               4698                 :                :  */
                               4699                 :                : static bool
 2560                          4700                 :            155 : is_superuser(Archive *fout)
                               4701                 :                : {
                               4702                 :            155 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                               4703                 :                :     const char *val;
                               4704                 :                : 
                               4705                 :            155 :     val = PQparameterStatus(AH->connection, "is_superuser");
                               4706                 :                : 
                               4707   [ +  -  +  + ]:            155 :     if (val && strcmp(val, "on") == 0)
                               4708                 :            152 :         return true;
                               4709                 :                : 
                               4710                 :              3 :     return false;
                               4711                 :                : }
                               4712                 :                : 
                               4713                 :                : /*
                               4714                 :                :  * getSubscriptions
                               4715                 :                :  *    get information about subscriptions
                               4716                 :                :  */
                               4717                 :                : void
 2642                          4718                 :            155 : getSubscriptions(Archive *fout)
                               4719                 :                : {
 2532                          4720                 :            155 :     DumpOptions *dopt = fout->dopt;
                               4721                 :                :     PQExpBuffer query;
                               4722                 :                :     PGresult   *res;
                               4723                 :                :     SubscriptionInfo *subinfo;
                               4724                 :                :     int         i_tableoid;
                               4725                 :                :     int         i_oid;
                               4726                 :                :     int         i_subname;
                               4727                 :                :     int         i_subowner;
                               4728                 :                :     int         i_subbinary;
                               4729                 :                :     int         i_substream;
                               4730                 :                :     int         i_subtwophasestate;
                               4731                 :                :     int         i_subdisableonerr;
                               4732                 :                :     int         i_subpasswordrequired;
                               4733                 :                :     int         i_subrunasowner;
                               4734                 :                :     int         i_subconninfo;
                               4735                 :                :     int         i_subslotname;
                               4736                 :                :     int         i_subsynccommit;
                               4737                 :                :     int         i_subpublications;
                               4738                 :                :     int         i_suborigin;
                               4739                 :                :     int         i_suboriginremotelsn;
                               4740                 :                :     int         i_subenabled;
                               4741                 :                :     int         i_subfailover;
                               4742                 :                :     int         i,
                               4743                 :                :                 ntups;
                               4744                 :                : 
                               4745   [ +  -  -  + ]:            155 :     if (dopt->no_subscriptions || fout->remoteVersion < 100000)
 2560 peter_e@gmx.net          4746                 :UBC           0 :         return;
                               4747                 :                : 
 2560 peter_e@gmx.net          4748         [ +  + ]:CBC         155 :     if (!is_superuser(fout))
                               4749                 :                :     {
                               4750                 :                :         int         n;
                               4751                 :                : 
                               4752                 :              3 :         res = ExecuteSqlQuery(fout,
                               4753                 :                :                               "SELECT count(*) FROM pg_subscription "
                               4754                 :                :                               "WHERE subdbid = (SELECT oid FROM pg_database"
                               4755                 :                :                               "                 WHERE datname = current_database())",
                               4756                 :                :                               PGRES_TUPLES_OK);
                               4757                 :              3 :         n = atoi(PQgetvalue(res, 0, 0));
                               4758         [ +  + ]:              3 :         if (n > 0)
 1840 peter@eisentraut.org     4759                 :              2 :             pg_log_warning("subscriptions not dumped because current user is not a superuser");
 2560 peter_e@gmx.net          4760                 :              3 :         PQclear(res);
 2642                          4761                 :              3 :         return;
                               4762                 :                :     }
                               4763                 :                : 
                               4764                 :            152 :     query = createPQExpBuffer();
                               4765                 :                : 
                               4766                 :                :     /* Get the subscriptions in current database. */
  586 drowley@postgresql.o     4767                 :            152 :     appendPQExpBufferStr(query,
                               4768                 :                :                          "SELECT s.tableoid, s.oid, s.subname,\n"
                               4769                 :                :                          " s.subowner,\n"
                               4770                 :                :                          " s.subconninfo, s.subslotname, s.subsynccommit,\n"
                               4771                 :                :                          " s.subpublications,\n");
                               4772                 :                : 
 1366 tgl@sss.pgh.pa.us        4773         [ +  - ]:            152 :     if (fout->remoteVersion >= 140000)
 1277 drowley@postgresql.o     4774                 :            152 :         appendPQExpBufferStr(query, " s.subbinary,\n");
                               4775                 :                :     else
 1277 drowley@postgresql.o     4776                 :UBC           0 :         appendPQExpBufferStr(query, " false AS subbinary,\n");
                               4777                 :                : 
 1319 akapila@postgresql.o     4778         [ +  - ]:CBC         152 :     if (fout->remoteVersion >= 140000)
 1005                          4779                 :            152 :         appendPQExpBufferStr(query, " s.substream,\n");
                               4780                 :                :     else
  461 akapila@postgresql.o     4781                 :UBC           0 :         appendPQExpBufferStr(query, " 'f' AS substream,\n");
                               4782                 :                : 
 1005 akapila@postgresql.o     4783         [ +  - ]:CBC         152 :     if (fout->remoteVersion >= 150000)
  762                          4784                 :            152 :         appendPQExpBufferStr(query,
                               4785                 :                :                              " s.subtwophasestate,\n"
                               4786                 :                :                              " s.subdisableonerr,\n");
                               4787                 :                :     else
 1005 akapila@postgresql.o     4788                 :UBC           0 :         appendPQExpBuffer(query,
                               4789                 :                :                           " '%c' AS subtwophasestate,\n"
                               4790                 :                :                           " false AS subdisableonerr,\n",
                               4791                 :                :                           LOGICALREP_TWOPHASE_STATE_DISABLED);
                               4792                 :                : 
  633 akapila@postgresql.o     4793         [ +  - ]:CBC         152 :     if (fout->remoteVersion >= 160000)
  381 rhaas@postgresql.org     4794                 :            152 :         appendPQExpBufferStr(query,
                               4795                 :                :                              " s.subpasswordrequired,\n"
                               4796                 :                :                              " s.subrunasowner,\n"
                               4797                 :                :                              " s.suborigin,\n");
                               4798                 :                :     else
  381 rhaas@postgresql.org     4799                 :UBC           0 :         appendPQExpBuffer(query,
                               4800                 :                :                           " 't' AS subpasswordrequired,\n"
                               4801                 :                :                           " 't' AS subrunasowner,\n"
                               4802                 :                :                           " '%s' AS suborigin,\n",
                               4803                 :                :                           LOGICALREP_ORIGIN_ANY);
                               4804                 :                : 
  103 akapila@postgresql.o     4805   [ +  +  +  - ]:GNC         152 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               4806                 :             14 :         appendPQExpBufferStr(query, " o.remote_lsn AS suboriginremotelsn,\n"
                               4807                 :                :                              " s.subenabled,\n"
                               4808                 :                :                              " s.subfailover\n");
                               4809                 :                :     else
                               4810                 :            138 :         appendPQExpBufferStr(query, " NULL AS suboriginremotelsn,\n"
                               4811                 :                :                              " false AS subenabled,\n"
                               4812                 :                :                              " false AS subfailover\n");
                               4813                 :                : 
                               4814                 :            152 :     appendPQExpBufferStr(query,
                               4815                 :                :                          "FROM pg_subscription s\n");
                               4816                 :                : 
                               4817   [ +  +  +  - ]:            152 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               4818                 :             14 :         appendPQExpBufferStr(query,
                               4819                 :                :                              "LEFT JOIN pg_catalog.pg_replication_origin_status o \n"
                               4820                 :                :                              "    ON o.external_id = 'pg_' || s.oid::text \n");
                               4821                 :                : 
 1277 drowley@postgresql.o     4822                 :CBC         152 :     appendPQExpBufferStr(query,
                               4823                 :                :                          "WHERE s.subdbid = (SELECT oid FROM pg_database\n"
                               4824                 :                :                          "                   WHERE datname = current_database())");
                               4825                 :                : 
 2642 peter_e@gmx.net          4826                 :            152 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               4827                 :                : 
                               4828                 :            152 :     ntups = PQntuples(res);
                               4829                 :                : 
                               4830                 :                :     /*
                               4831                 :                :      * Get subscription fields. We don't include subskiplsn in the dump as
                               4832                 :                :      * after restoring the dump this value may no longer be relevant.
                               4833                 :                :      */
                               4834                 :            152 :     i_tableoid = PQfnumber(res, "tableoid");
                               4835                 :            152 :     i_oid = PQfnumber(res, "oid");
                               4836                 :            152 :     i_subname = PQfnumber(res, "subname");
  835 tgl@sss.pgh.pa.us        4837                 :            152 :     i_subowner = PQfnumber(res, "subowner");
 1366                          4838                 :            152 :     i_subbinary = PQfnumber(res, "subbinary");
 1319 akapila@postgresql.o     4839                 :            152 :     i_substream = PQfnumber(res, "substream");
 1005                          4840                 :            152 :     i_subtwophasestate = PQfnumber(res, "subtwophasestate");
  762                          4841                 :            152 :     i_subdisableonerr = PQfnumber(res, "subdisableonerr");
  381 rhaas@postgresql.org     4842                 :            152 :     i_subpasswordrequired = PQfnumber(res, "subpasswordrequired");
  168 tgl@sss.pgh.pa.us        4843                 :            152 :     i_subrunasowner = PQfnumber(res, "subrunasowner");
                               4844                 :            152 :     i_subconninfo = PQfnumber(res, "subconninfo");
                               4845                 :            152 :     i_subslotname = PQfnumber(res, "subslotname");
                               4846                 :            152 :     i_subsynccommit = PQfnumber(res, "subsynccommit");
                               4847                 :            152 :     i_subpublications = PQfnumber(res, "subpublications");
                               4848                 :            152 :     i_suborigin = PQfnumber(res, "suborigin");
  103 akapila@postgresql.o     4849                 :GNC         152 :     i_suboriginremotelsn = PQfnumber(res, "suboriginremotelsn");
                               4850                 :            152 :     i_subenabled = PQfnumber(res, "subenabled");
   75                          4851                 :            152 :     i_subfailover = PQfnumber(res, "subfailover");
                               4852                 :                : 
 2642 peter_e@gmx.net          4853                 :CBC         152 :     subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo));
                               4854                 :                : 
                               4855         [ +  + ]:            286 :     for (i = 0; i < ntups; i++)
                               4856                 :                :     {
                               4857                 :            134 :         subinfo[i].dobj.objType = DO_SUBSCRIPTION;
                               4858                 :            134 :         subinfo[i].dobj.catId.tableoid =
                               4859                 :            134 :             atooid(PQgetvalue(res, i, i_tableoid));
                               4860                 :            134 :         subinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               4861                 :            134 :         AssignDumpId(&subinfo[i].dobj);
                               4862                 :            134 :         subinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_subname));
  835 tgl@sss.pgh.pa.us        4863                 :            134 :         subinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_subowner));
                               4864                 :                : 
 1366                          4865                 :            268 :         subinfo[i].subbinary =
                               4866                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subbinary));
 1319 akapila@postgresql.o     4867                 :            268 :         subinfo[i].substream =
                               4868                 :            134 :             pg_strdup(PQgetvalue(res, i, i_substream));
 1005                          4869                 :            268 :         subinfo[i].subtwophasestate =
                               4870                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subtwophasestate));
  762                          4871                 :            268 :         subinfo[i].subdisableonerr =
                               4872                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subdisableonerr));
  381 rhaas@postgresql.org     4873                 :            268 :         subinfo[i].subpasswordrequired =
                               4874                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subpasswordrequired));
  168 tgl@sss.pgh.pa.us        4875                 :            268 :         subinfo[i].subrunasowner =
                               4876                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subrunasowner));
                               4877                 :            268 :         subinfo[i].subconninfo =
                               4878                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subconninfo));
                               4879         [ -  + ]:            134 :         if (PQgetisnull(res, i, i_subslotname))
  168 tgl@sss.pgh.pa.us        4880                 :UBC           0 :             subinfo[i].subslotname = NULL;
                               4881                 :                :         else
  168 tgl@sss.pgh.pa.us        4882                 :CBC         134 :             subinfo[i].subslotname =
                               4883                 :            134 :                 pg_strdup(PQgetvalue(res, i, i_subslotname));
                               4884                 :            268 :         subinfo[i].subsynccommit =
                               4885                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subsynccommit));
                               4886                 :            268 :         subinfo[i].subpublications =
                               4887                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subpublications));
                               4888                 :            134 :         subinfo[i].suborigin = pg_strdup(PQgetvalue(res, i, i_suborigin));
  103 akapila@postgresql.o     4889         [ +  + ]:GNC         134 :         if (PQgetisnull(res, i, i_suboriginremotelsn))
                               4890                 :            133 :             subinfo[i].suboriginremotelsn = NULL;
                               4891                 :                :         else
                               4892                 :              1 :             subinfo[i].suboriginremotelsn =
                               4893                 :              1 :                 pg_strdup(PQgetvalue(res, i, i_suboriginremotelsn));
                               4894                 :            268 :         subinfo[i].subenabled =
                               4895                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subenabled));
   75                          4896                 :            268 :         subinfo[i].subfailover =
                               4897                 :            134 :             pg_strdup(PQgetvalue(res, i, i_subfailover));
                               4898                 :                : 
                               4899                 :                :         /* Decide whether we want to dump it */
 2560 peter_e@gmx.net          4900                 :CBC         134 :         selectDumpableObject(&(subinfo[i].dobj), fout);
                               4901                 :                :     }
 2642                          4902                 :            152 :     PQclear(res);
                               4903                 :                : 
                               4904                 :            152 :     destroyPQExpBuffer(query);
                               4905                 :                : }
                               4906                 :                : 
                               4907                 :                : /*
                               4908                 :                :  * getSubscriptionTables
                               4909                 :                :  *    Get information about subscription membership for dumpable tables. This
                               4910                 :                :  *    will be used only in binary-upgrade mode for PG17 or later versions.
                               4911                 :                :  */
                               4912                 :                : void
  103 akapila@postgresql.o     4913                 :GNC         155 : getSubscriptionTables(Archive *fout)
                               4914                 :                : {
                               4915                 :            155 :     DumpOptions *dopt = fout->dopt;
                               4916                 :            155 :     SubscriptionInfo *subinfo = NULL;
                               4917                 :                :     SubRelInfo *subrinfo;
                               4918                 :                :     PGresult   *res;
                               4919                 :                :     int         i_srsubid;
                               4920                 :                :     int         i_srrelid;
                               4921                 :                :     int         i_srsubstate;
                               4922                 :                :     int         i_srsublsn;
                               4923                 :                :     int         ntups;
                               4924                 :            155 :     Oid         last_srsubid = InvalidOid;
                               4925                 :                : 
                               4926   [ +  -  +  + ]:            155 :     if (dopt->no_subscriptions || !dopt->binary_upgrade ||
                               4927         [ -  + ]:             14 :         fout->remoteVersion < 170000)
                               4928                 :            141 :         return;
                               4929                 :                : 
                               4930                 :             14 :     res = ExecuteSqlQuery(fout,
                               4931                 :                :                           "SELECT srsubid, srrelid, srsubstate, srsublsn "
                               4932                 :                :                           "FROM pg_catalog.pg_subscription_rel "
                               4933                 :                :                           "ORDER BY srsubid",
                               4934                 :                :                           PGRES_TUPLES_OK);
                               4935                 :             14 :     ntups = PQntuples(res);
                               4936         [ +  + ]:             14 :     if (ntups == 0)
                               4937                 :             13 :         goto cleanup;
                               4938                 :                : 
                               4939                 :                :     /* Get pg_subscription_rel attributes */
                               4940                 :              1 :     i_srsubid = PQfnumber(res, "srsubid");
                               4941                 :              1 :     i_srrelid = PQfnumber(res, "srrelid");
                               4942                 :              1 :     i_srsubstate = PQfnumber(res, "srsubstate");
                               4943                 :              1 :     i_srsublsn = PQfnumber(res, "srsublsn");
                               4944                 :                : 
                               4945                 :              1 :     subrinfo = pg_malloc(ntups * sizeof(SubRelInfo));
                               4946         [ +  + ]:              3 :     for (int i = 0; i < ntups; i++)
                               4947                 :                :     {
                               4948                 :              2 :         Oid         cur_srsubid = atooid(PQgetvalue(res, i, i_srsubid));
                               4949                 :              2 :         Oid         relid = atooid(PQgetvalue(res, i, i_srrelid));
                               4950                 :                :         TableInfo  *tblinfo;
                               4951                 :                : 
                               4952                 :                :         /*
                               4953                 :                :          * If we switched to a new subscription, check if the subscription
                               4954                 :                :          * exists.
                               4955                 :                :          */
                               4956         [ +  - ]:              2 :         if (cur_srsubid != last_srsubid)
                               4957                 :                :         {
                               4958                 :              2 :             subinfo = findSubscriptionByOid(cur_srsubid);
                               4959         [ -  + ]:              2 :             if (subinfo == NULL)
  103 akapila@postgresql.o     4960                 :UNC           0 :                 pg_fatal("subscription with OID %u does not exist", cur_srsubid);
                               4961                 :                : 
  103 akapila@postgresql.o     4962                 :GNC           2 :             last_srsubid = cur_srsubid;
                               4963                 :                :         }
                               4964                 :                : 
                               4965                 :              2 :         tblinfo = findTableByOid(relid);
                               4966         [ -  + ]:              2 :         if (tblinfo == NULL)
  103 akapila@postgresql.o     4967                 :UNC           0 :             pg_fatal("failed sanity check, table with OID %u not found",
                               4968                 :                :                      relid);
                               4969                 :                : 
                               4970                 :                :         /* OK, make a DumpableObject for this relationship */
  103 akapila@postgresql.o     4971                 :GNC           2 :         subrinfo[i].dobj.objType = DO_SUBSCRIPTION_REL;
                               4972                 :              2 :         subrinfo[i].dobj.catId.tableoid = relid;
                               4973                 :              2 :         subrinfo[i].dobj.catId.oid = cur_srsubid;
                               4974                 :              2 :         AssignDumpId(&subrinfo[i].dobj);
                               4975                 :              2 :         subrinfo[i].dobj.name = pg_strdup(subinfo->dobj.name);
                               4976                 :              2 :         subrinfo[i].tblinfo = tblinfo;
                               4977                 :              2 :         subrinfo[i].srsubstate = PQgetvalue(res, i, i_srsubstate)[0];
                               4978         [ +  + ]:              2 :         if (PQgetisnull(res, i, i_srsublsn))
                               4979                 :              1 :             subrinfo[i].srsublsn = NULL;
                               4980                 :                :         else
                               4981                 :              1 :             subrinfo[i].srsublsn = pg_strdup(PQgetvalue(res, i, i_srsublsn));
                               4982                 :                : 
                               4983                 :              2 :         subrinfo[i].subinfo = subinfo;
                               4984                 :                : 
                               4985                 :                :         /* Decide whether we want to dump it */
                               4986                 :              2 :         selectDumpableObject(&(subrinfo[i].dobj), fout);
                               4987                 :                :     }
                               4988                 :                : 
                               4989                 :              1 : cleanup:
                               4990                 :             14 :     PQclear(res);
                               4991                 :                : }
                               4992                 :                : 
                               4993                 :                : /*
                               4994                 :                :  * dumpSubscriptionTable
                               4995                 :                :  *    Dump the definition of the given subscription table mapping. This will be
                               4996                 :                :  *    used only in binary-upgrade mode for PG17 or later versions.
                               4997                 :                :  */
                               4998                 :                : static void
                               4999                 :              2 : dumpSubscriptionTable(Archive *fout, const SubRelInfo *subrinfo)
                               5000                 :                : {
                               5001                 :              2 :     DumpOptions *dopt = fout->dopt;
                               5002                 :              2 :     SubscriptionInfo *subinfo = subrinfo->subinfo;
                               5003                 :                :     PQExpBuffer query;
                               5004                 :                :     char       *tag;
                               5005                 :                : 
                               5006                 :                :     /* Do nothing in data-only dump */
                               5007         [ -  + ]:              2 :     if (dopt->dataOnly)
  103 akapila@postgresql.o     5008                 :UNC           0 :         return;
                               5009                 :                : 
  103 akapila@postgresql.o     5010   [ +  -  +  - ]:GNC           2 :     Assert(fout->dopt->binary_upgrade && fout->remoteVersion >= 170000);
                               5011                 :                : 
                               5012                 :              2 :     tag = psprintf("%s %s", subinfo->dobj.name, subrinfo->dobj.name);
                               5013                 :                : 
                               5014                 :              2 :     query = createPQExpBuffer();
                               5015                 :                : 
                               5016         [ +  - ]:              2 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5017                 :                :     {
                               5018                 :                :         /*
                               5019                 :                :          * binary_upgrade_add_sub_rel_state will add the subscription relation
                               5020                 :                :          * to pg_subscription_rel table. This will be used only in
                               5021                 :                :          * binary-upgrade mode.
                               5022                 :                :          */
                               5023                 :              2 :         appendPQExpBufferStr(query,
                               5024                 :                :                              "\n-- For binary upgrade, must preserve the subscriber table.\n");
                               5025                 :              2 :         appendPQExpBufferStr(query,
                               5026                 :                :                              "SELECT pg_catalog.binary_upgrade_add_sub_rel_state(");
                               5027                 :              2 :         appendStringLiteralAH(query, subrinfo->dobj.name, fout);
                               5028                 :              2 :         appendPQExpBuffer(query,
                               5029                 :                :                           ", %u, '%c'",
                               5030                 :              2 :                           subrinfo->tblinfo->dobj.catId.oid,
                               5031                 :              2 :                           subrinfo->srsubstate);
                               5032                 :                : 
                               5033   [ +  +  +  - ]:              2 :         if (subrinfo->srsublsn && subrinfo->srsublsn[0] != '\0')
                               5034                 :              1 :             appendPQExpBuffer(query, ", '%s'", subrinfo->srsublsn);
                               5035                 :                :         else
                               5036                 :              1 :             appendPQExpBuffer(query, ", NULL");
                               5037                 :                : 
                               5038                 :              2 :         appendPQExpBufferStr(query, ");\n");
                               5039                 :                :     }
                               5040                 :                : 
                               5041                 :                :     /*
                               5042                 :                :      * There is no point in creating a drop query as the drop is done by table
                               5043                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                               5044                 :                :      * Although this object doesn't really have ownership as such, set the
                               5045                 :                :      * owner field anyway to ensure that the command is run by the correct
                               5046                 :                :      * role at restore time.
                               5047                 :                :      */
                               5048         [ +  - ]:              2 :     if (subrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5049                 :              2 :         ArchiveEntry(fout, subrinfo->dobj.catId, subrinfo->dobj.dumpId,
                               5050                 :              2 :                      ARCHIVE_OPTS(.tag = tag,
                               5051                 :                :                                   .namespace = subrinfo->tblinfo->dobj.namespace->dobj.name,
                               5052                 :                :                                   .owner = subinfo->rolname,
                               5053                 :                :                                   .description = "SUBSCRIPTION TABLE",
                               5054                 :                :                                   .section = SECTION_POST_DATA,
                               5055                 :                :                                   .createStmt = query->data));
                               5056                 :                : 
                               5057                 :                :     /* These objects can't currently have comments or seclabels */
                               5058                 :                : 
                               5059                 :              2 :     free(tag);
                               5060                 :              2 :     destroyPQExpBuffer(query);
                               5061                 :                : }
                               5062                 :                : 
                               5063                 :                : /*
                               5064                 :                :  * dumpSubscription
                               5065                 :                :  *    dump the definition of the given subscription
                               5066                 :                :  */
                               5067                 :                : static void
 1159 peter@eisentraut.org     5068                 :CBC         116 : dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo)
                               5069                 :                : {
  836 tgl@sss.pgh.pa.us        5070                 :            116 :     DumpOptions *dopt = fout->dopt;
                               5071                 :                :     PQExpBuffer delq;
                               5072                 :                :     PQExpBuffer query;
                               5073                 :                :     PQExpBuffer publications;
                               5074                 :                :     char       *qsubname;
 2642 peter_e@gmx.net          5075                 :            116 :     char      **pubnames = NULL;
                               5076                 :            116 :     int         npubnames = 0;
                               5077                 :                :     int         i;
 1005 akapila@postgresql.o     5078                 :            116 :     char        two_phase_disabled[] = {LOGICALREP_TWOPHASE_STATE_DISABLED, '\0'};
                               5079                 :                : 
                               5080                 :                :     /* Do nothing in data-only dump */
  836 tgl@sss.pgh.pa.us        5081         [ +  + ]:            116 :     if (dopt->dataOnly)
                               5082                 :              9 :         return;
                               5083                 :                : 
 2642 peter_e@gmx.net          5084                 :            107 :     delq = createPQExpBuffer();
                               5085                 :            107 :     query = createPQExpBuffer();
                               5086                 :                : 
 2239 tgl@sss.pgh.pa.us        5087                 :            107 :     qsubname = pg_strdup(fmtId(subinfo->dobj.name));
                               5088                 :                : 
 2642 peter_e@gmx.net          5089                 :            107 :     appendPQExpBuffer(delq, "DROP SUBSCRIPTION %s;\n",
                               5090                 :                :                       qsubname);
                               5091                 :                : 
                               5092                 :            107 :     appendPQExpBuffer(query, "CREATE SUBSCRIPTION %s CONNECTION ",
                               5093                 :                :                       qsubname);
                               5094                 :            107 :     appendStringLiteralAH(query, subinfo->subconninfo, fout);
                               5095                 :                : 
                               5096                 :                :     /* Build list of quoted publications and append them to query. */
                               5097         [ -  + ]:            107 :     if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames))
  737 tgl@sss.pgh.pa.us        5098                 :UBC           0 :         pg_fatal("could not parse %s array", "subpublications");
                               5099                 :                : 
 2642 peter_e@gmx.net          5100                 :CBC         107 :     publications = createPQExpBuffer();
                               5101         [ +  + ]:            214 :     for (i = 0; i < npubnames; i++)
                               5102                 :                :     {
                               5103         [ -  + ]:            107 :         if (i > 0)
 2642 peter_e@gmx.net          5104                 :UBC           0 :             appendPQExpBufferStr(publications, ", ");
                               5105                 :                : 
 2642 peter_e@gmx.net          5106                 :CBC         107 :         appendPQExpBufferStr(publications, fmtId(pubnames[i]));
                               5107                 :                :     }
                               5108                 :                : 
 2529                          5109                 :            107 :     appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
 2524                          5110         [ +  - ]:            107 :     if (subinfo->subslotname)
                               5111                 :            107 :         appendStringLiteralAH(query, subinfo->subslotname, fout);
                               5112                 :                :     else
 2524 peter_e@gmx.net          5113                 :UBC           0 :         appendPQExpBufferStr(query, "NONE");
                               5114                 :                : 
 1366 tgl@sss.pgh.pa.us        5115         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subbinary, "t") == 0)
 1277 drowley@postgresql.o     5116                 :UBC           0 :         appendPQExpBufferStr(query, ", binary = true");
                               5117                 :                : 
  461 akapila@postgresql.o     5118         [ -  + ]:CBC         107 :     if (strcmp(subinfo->substream, "t") == 0)
 1277 drowley@postgresql.o     5119                 :UBC           0 :         appendPQExpBufferStr(query, ", streaming = on");
  461 akapila@postgresql.o     5120         [ -  + ]:CBC         107 :     else if (strcmp(subinfo->substream, "p") == 0)
  461 akapila@postgresql.o     5121                 :UBC           0 :         appendPQExpBufferStr(query, ", streaming = parallel");
                               5122                 :                : 
 1005 akapila@postgresql.o     5123         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subtwophasestate, two_phase_disabled) != 0)
 1005 akapila@postgresql.o     5124                 :UBC           0 :         appendPQExpBufferStr(query, ", two_phase = on");
                               5125                 :                : 
  762 akapila@postgresql.o     5126         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subdisableonerr, "t") == 0)
  762 akapila@postgresql.o     5127                 :UBC           0 :         appendPQExpBufferStr(query, ", disable_on_error = true");
                               5128                 :                : 
  168 tgl@sss.pgh.pa.us        5129         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subpasswordrequired, "t") != 0)
  168 tgl@sss.pgh.pa.us        5130                 :UBC           0 :         appendPQExpBuffer(query, ", password_required = false");
                               5131                 :                : 
  168 tgl@sss.pgh.pa.us        5132         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subrunasowner, "t") == 0)
  168 tgl@sss.pgh.pa.us        5133                 :UBC           0 :         appendPQExpBufferStr(query, ", run_as_owner = true");
                               5134                 :                : 
 2557 peter_e@gmx.net          5135         [ -  + ]:CBC         107 :     if (strcmp(subinfo->subsynccommit, "off") != 0)
 2529 peter_e@gmx.net          5136                 :UBC           0 :         appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
                               5137                 :                : 
  168 tgl@sss.pgh.pa.us        5138         [ +  + ]:CBC         107 :     if (pg_strcasecmp(subinfo->suborigin, LOGICALREP_ORIGIN_ANY) != 0)
                               5139                 :             35 :         appendPQExpBuffer(query, ", origin = %s", subinfo->suborigin);
                               5140                 :                : 
 2642 peter_e@gmx.net          5141                 :            107 :     appendPQExpBufferStr(query, ");\n");
                               5142                 :                : 
                               5143                 :                :     /*
                               5144                 :                :      * In binary-upgrade mode, we allow the replication to continue after the
                               5145                 :                :      * upgrade.
                               5146                 :                :      */
  103 akapila@postgresql.o     5147   [ +  +  +  - ]:GNC         107 :     if (dopt->binary_upgrade && fout->remoteVersion >= 170000)
                               5148                 :                :     {
                               5149         [ +  + ]:              5 :         if (subinfo->suboriginremotelsn)
                               5150                 :                :         {
                               5151                 :                :             /*
                               5152                 :                :              * Preserve the remote_lsn for the subscriber's replication
                               5153                 :                :              * origin. This value is required to start the replication from
                               5154                 :                :              * the position before the upgrade. This value will be stale if
                               5155                 :                :              * the publisher gets upgraded before the subscriber node.
                               5156                 :                :              * However, this shouldn't be a problem as the upgrade of the
                               5157                 :                :              * publisher ensures that all the transactions were replicated
                               5158                 :                :              * before upgrading it.
                               5159                 :                :              */
                               5160                 :              1 :             appendPQExpBufferStr(query,
                               5161                 :                :                                  "\n-- For binary upgrade, must preserve the remote_lsn for the subscriber's replication origin.\n");
                               5162                 :              1 :             appendPQExpBufferStr(query,
                               5163                 :                :                                  "SELECT pg_catalog.binary_upgrade_replorigin_advance(");
                               5164                 :              1 :             appendStringLiteralAH(query, subinfo->dobj.name, fout);
                               5165                 :              1 :             appendPQExpBuffer(query, ", '%s');\n", subinfo->suboriginremotelsn);
                               5166                 :                :         }
                               5167                 :                : 
   75                          5168         [ +  + ]:              5 :         if (strcmp(subinfo->subfailover, "t") == 0)
                               5169                 :                :         {
                               5170                 :                :             /*
                               5171                 :                :              * Enable the failover to allow the subscription's slot to be
                               5172                 :                :              * synced to the standbys after the upgrade.
                               5173                 :                :              */
                               5174                 :              1 :             appendPQExpBufferStr(query,
                               5175                 :                :                                  "\n-- For binary upgrade, must preserve the subscriber's failover option.\n");
                               5176                 :              1 :             appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s SET(failover = true);\n", qsubname);
                               5177                 :                :         }
                               5178                 :                : 
  103                          5179         [ +  + ]:              5 :         if (strcmp(subinfo->subenabled, "t") == 0)
                               5180                 :                :         {
                               5181                 :                :             /*
                               5182                 :                :              * Enable the subscription to allow the replication to continue
                               5183                 :                :              * after the upgrade.
                               5184                 :                :              */
                               5185                 :              1 :             appendPQExpBufferStr(query,
                               5186                 :                :                                  "\n-- For binary upgrade, must preserve the subscriber's running state.\n");
                               5187                 :              1 :             appendPQExpBuffer(query, "ALTER SUBSCRIPTION %s ENABLE;\n", qsubname);
                               5188                 :                :         }
                               5189                 :                :     }
                               5190                 :                : 
  860 tgl@sss.pgh.pa.us        5191         [ +  - ]:CBC         107 :     if (subinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                               5192                 :            107 :         ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId,
                               5193                 :            107 :                      ARCHIVE_OPTS(.tag = subinfo->dobj.name,
                               5194                 :                :                                   .owner = subinfo->rolname,
                               5195                 :                :                                   .description = "SUBSCRIPTION",
                               5196                 :                :                                   .section = SECTION_POST_DATA,
                               5197                 :                :                                   .createStmt = query->data,
                               5198                 :                :                                   .dropStmt = delq->data));
                               5199                 :                : 
 2558 peter_e@gmx.net          5200         [ +  + ]:            107 :     if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us        5201                 :             35 :         dumpComment(fout, "SUBSCRIPTION", qsubname,
 2558 peter_e@gmx.net          5202                 :             35 :                     NULL, subinfo->rolname,
                               5203                 :             35 :                     subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5204                 :                : 
                               5205         [ -  + ]:            107 :     if (subinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us        5206                 :UBC           0 :         dumpSecLabel(fout, "SUBSCRIPTION", qsubname,
 2558 peter_e@gmx.net          5207                 :              0 :                      NULL, subinfo->rolname,
                               5208                 :              0 :                      subinfo->dobj.catId, 0, subinfo->dobj.dumpId);
                               5209                 :                : 
 2642 peter_e@gmx.net          5210                 :CBC         107 :     destroyPQExpBuffer(publications);
  668 peter@eisentraut.org     5211                 :            107 :     free(pubnames);
                               5212                 :                : 
 2642 peter_e@gmx.net          5213                 :            107 :     destroyPQExpBuffer(delq);
                               5214                 :            107 :     destroyPQExpBuffer(query);
 2239 tgl@sss.pgh.pa.us        5215                 :            107 :     free(qsubname);
                               5216                 :                : }
                               5217                 :                : 
                               5218                 :                : /*
                               5219                 :                :  * Given a "create query", append as many ALTER ... DEPENDS ON EXTENSION as
                               5220                 :                :  * the object needs.
                               5221                 :                :  */
                               5222                 :                : static void
 1495 alvherre@alvh.no-ip.     5223                 :           4772 : append_depends_on_extension(Archive *fout,
                               5224                 :                :                             PQExpBuffer create,
                               5225                 :                :                             const DumpableObject *dobj,
                               5226                 :                :                             const char *catalog,
                               5227                 :                :                             const char *keyword,
                               5228                 :                :                             const char *objname)
                               5229                 :                : {
                               5230         [ +  + ]:           4772 :     if (dobj->depends_on_ext)
                               5231                 :                :     {
                               5232                 :                :         char       *nm;
                               5233                 :                :         PGresult   *res;
                               5234                 :                :         PQExpBuffer query;
                               5235                 :                :         int         ntups;
                               5236                 :                :         int         i_extname;
                               5237                 :                :         int         i;
                               5238                 :                : 
                               5239                 :                :         /* dodge fmtId() non-reentrancy */
                               5240                 :             42 :         nm = pg_strdup(objname);
                               5241                 :                : 
                               5242                 :             42 :         query = createPQExpBuffer();
                               5243                 :             42 :         appendPQExpBuffer(query,
                               5244                 :                :                           "SELECT e.extname "
                               5245                 :                :                           "FROM pg_catalog.pg_depend d, pg_catalog.pg_extension e "
                               5246                 :                :                           "WHERE d.refobjid = e.oid AND classid = '%s'::pg_catalog.regclass "
                               5247                 :                :                           "AND objid = '%u'::pg_catalog.oid AND deptype = 'x' "
                               5248                 :                :                           "AND refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass",
                               5249                 :                :                           catalog,
                               5250                 :             42 :                           dobj->catId.oid);
                               5251                 :             42 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5252                 :             42 :         ntups = PQntuples(res);
                               5253                 :             42 :         i_extname = PQfnumber(res, "extname");
                               5254         [ +  + ]:             84 :         for (i = 0; i < ntups; i++)
                               5255                 :                :         {
  233 alvherre@alvh.no-ip.     5256                 :GNC          42 :             appendPQExpBuffer(create, "\nALTER %s %s DEPENDS ON EXTENSION %s;",
                               5257                 :                :                               keyword, nm,
 1495 alvherre@alvh.no-ip.     5258                 :CBC          42 :                               fmtId(PQgetvalue(res, i, i_extname)));
                               5259                 :                :         }
                               5260                 :                : 
                               5261                 :             42 :         PQclear(res);
 1490                          5262                 :             42 :         destroyPQExpBuffer(query);
 1495                          5263                 :             42 :         pg_free(nm);
                               5264                 :                :     }
                               5265                 :           4772 : }
                               5266                 :                : 
                               5267                 :                : static Oid
 1211 akorotkov@postgresql     5268                 :UBC           0 : get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query)
                               5269                 :                : {
                               5270                 :                :     /*
                               5271                 :                :      * If the old version didn't assign an array type, but the new version
                               5272                 :                :      * does, we must select an unused type OID to assign.  This currently only
                               5273                 :                :      * happens for domains, when upgrading pre-v11 to v11 and up.
                               5274                 :                :      *
                               5275                 :                :      * Note: local state here is kind of ugly, but we must have some, since we
                               5276                 :                :      * mustn't choose the same unused OID more than once.
                               5277                 :                :      */
                               5278                 :                :     static Oid  next_possible_free_oid = FirstNormalObjectId;
                               5279                 :                :     PGresult   *res;
                               5280                 :                :     bool        is_dup;
                               5281                 :                : 
                               5282                 :                :     do
                               5283                 :                :     {
                               5284                 :              0 :         ++next_possible_free_oid;
                               5285                 :              0 :         printfPQExpBuffer(upgrade_query,
                               5286                 :                :                           "SELECT EXISTS(SELECT 1 "
                               5287                 :                :                           "FROM pg_catalog.pg_type "
                               5288                 :                :                           "WHERE oid = '%u'::pg_catalog.oid);",
                               5289                 :                :                           next_possible_free_oid);
                               5290                 :              0 :         res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5291                 :              0 :         is_dup = (PQgetvalue(res, 0, 0)[0] == 't');
                               5292                 :              0 :         PQclear(res);
                               5293         [ #  # ]:              0 :     } while (is_dup);
                               5294                 :                : 
                               5295                 :              0 :     return next_possible_free_oid;
                               5296                 :                : }
                               5297                 :                : 
                               5298                 :                : static void
 4450 rhaas@postgresql.org     5299                 :CBC         827 : binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                               5300                 :                :                                          PQExpBuffer upgrade_buffer,
                               5301                 :                :                                          Oid pg_type_oid,
                               5302                 :                :                                          bool force_array_type,
                               5303                 :                :                                          bool include_multirange_type)
                               5304                 :                : {
 5225 bruce@momjian.us         5305                 :            827 :     PQExpBuffer upgrade_query = createPQExpBuffer();
                               5306                 :                :     PGresult   *res;
                               5307                 :                :     Oid         pg_type_array_oid;
                               5308                 :                :     Oid         pg_type_multirange_oid;
                               5309                 :                :     Oid         pg_type_multirange_array_oid;
                               5310                 :                : 
 3800 heikki.linnakangas@i     5311                 :            827 :     appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
 5225 bruce@momjian.us         5312                 :            827 :     appendPQExpBuffer(upgrade_buffer,
                               5313                 :                :                       "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5314                 :                :                       pg_type_oid);
                               5315                 :                : 
                               5316                 :            827 :     appendPQExpBuffer(upgrade_query,
                               5317                 :                :                       "SELECT typarray "
                               5318                 :                :                       "FROM pg_catalog.pg_type "
                               5319                 :                :                       "WHERE oid = '%u'::pg_catalog.oid;",
                               5320                 :                :                       pg_type_oid);
                               5321                 :                : 
 2388 tgl@sss.pgh.pa.us        5322                 :            827 :     res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5323                 :                : 
                               5324                 :            827 :     pg_type_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
                               5325                 :                : 
                               5326                 :            827 :     PQclear(res);
                               5327                 :                : 
                               5328   [ +  +  -  + ]:            827 :     if (!OidIsValid(pg_type_array_oid) && force_array_type)
 1211 akorotkov@postgresql     5329                 :UBC           0 :         pg_type_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5330                 :                : 
 5225 bruce@momjian.us         5331         [ +  + ]:CBC         827 :     if (OidIsValid(pg_type_array_oid))
                               5332                 :                :     {
 3800 heikki.linnakangas@i     5333                 :            825 :         appendPQExpBufferStr(upgrade_buffer,
                               5334                 :                :                              "\n-- For binary upgrade, must preserve pg_type array oid\n");
 5225 bruce@momjian.us         5335                 :            825 :         appendPQExpBuffer(upgrade_buffer,
                               5336                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5337                 :                :                           pg_type_array_oid);
                               5338                 :                :     }
                               5339                 :                : 
                               5340                 :                :     /*
                               5341                 :                :      * Pre-set the multirange type oid and its own array type oid.
                               5342                 :                :      */
 1211 akorotkov@postgresql     5343         [ +  + ]:            827 :     if (include_multirange_type)
                               5344                 :                :     {
                               5345         [ +  - ]:              6 :         if (fout->remoteVersion >= 140000)
                               5346                 :                :         {
  812 tgl@sss.pgh.pa.us        5347                 :              6 :             printfPQExpBuffer(upgrade_query,
                               5348                 :                :                               "SELECT t.oid, t.typarray "
                               5349                 :                :                               "FROM pg_catalog.pg_type t "
                               5350                 :                :                               "JOIN pg_catalog.pg_range r "
                               5351                 :                :                               "ON t.oid = r.rngmultitypid "
                               5352                 :                :                               "WHERE r.rngtypid = '%u'::pg_catalog.oid;",
                               5353                 :                :                               pg_type_oid);
                               5354                 :                : 
 1211 akorotkov@postgresql     5355                 :              6 :             res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5356                 :                : 
                               5357                 :              6 :             pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
                               5358                 :              6 :             pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray")));
                               5359                 :                : 
                               5360                 :              6 :             PQclear(res);
                               5361                 :                :         }
                               5362                 :                :         else
                               5363                 :                :         {
 1211 akorotkov@postgresql     5364                 :UBC           0 :             pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5365                 :              0 :             pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query);
                               5366                 :                :         }
                               5367                 :                : 
 1211 akorotkov@postgresql     5368                 :CBC           6 :         appendPQExpBufferStr(upgrade_buffer,
                               5369                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type oid\n");
                               5370                 :              6 :         appendPQExpBuffer(upgrade_buffer,
                               5371                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5372                 :                :                           pg_type_multirange_oid);
                               5373                 :              6 :         appendPQExpBufferStr(upgrade_buffer,
                               5374                 :                :                              "\n-- For binary upgrade, must preserve multirange pg_type array oid\n");
                               5375                 :              6 :         appendPQExpBuffer(upgrade_buffer,
                               5376                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                               5377                 :                :                           pg_type_multirange_array_oid);
                               5378                 :                :     }
                               5379                 :                : 
 5225 bruce@momjian.us         5380                 :            827 :     destroyPQExpBuffer(upgrade_query);
                               5381                 :            827 : }
                               5382                 :                : 
                               5383                 :                : static void
  860 tgl@sss.pgh.pa.us        5384                 :            760 : binary_upgrade_set_type_oids_by_rel(Archive *fout,
                               5385                 :                :                                     PQExpBuffer upgrade_buffer,
                               5386                 :                :                                     const TableInfo *tbinfo)
                               5387                 :                : {
                               5388                 :            760 :     Oid         pg_type_oid = tbinfo->reltype;
                               5389                 :                : 
 1377                          5390         [ +  - ]:            760 :     if (OidIsValid(pg_type_oid))
                               5391                 :            760 :         binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
                               5392                 :                :                                                  pg_type_oid, false, false);
 5225 bruce@momjian.us         5393                 :            760 : }
                               5394                 :                : 
                               5395                 :                : static void
 4450 rhaas@postgresql.org     5396                 :           1119 : binary_upgrade_set_pg_class_oids(Archive *fout,
                               5397                 :                :                                  PQExpBuffer upgrade_buffer, Oid pg_class_oid,
                               5398                 :                :                                  bool is_index)
                               5399                 :                : {
  818                          5400                 :           1119 :     PQExpBuffer upgrade_query = createPQExpBuffer();
                               5401                 :                :     PGresult   *upgrade_res;
                               5402                 :                :     RelFileNumber relfilenumber;
                               5403                 :                :     Oid         toast_oid;
                               5404                 :                :     RelFileNumber toast_relfilenumber;
                               5405                 :                :     char        relkind;
                               5406                 :                :     Oid         toast_index_oid;
                               5407                 :                :     RelFileNumber toast_index_relfilenumber;
                               5408                 :                : 
                               5409                 :                :     /*
                               5410                 :                :      * Preserve the OID and relfilenumber of the table, table's index, table's
                               5411                 :                :      * toast table and toast table's index if any.
                               5412                 :                :      *
                               5413                 :                :      * One complexity is that the current table definition might not require
                               5414                 :                :      * the creation of a TOAST table, but the old database might have a TOAST
                               5415                 :                :      * table that was created earlier, before some wide columns were dropped.
                               5416                 :                :      * By setting the TOAST oid we force creation of the TOAST heap and index
                               5417                 :                :      * by the new backend, so we can copy the files during binary upgrade
                               5418                 :                :      * without worrying about this case.
                               5419                 :                :      */
                               5420                 :           1119 :     appendPQExpBuffer(upgrade_query,
                               5421                 :                :                       "SELECT c.relkind, c.relfilenode, c.reltoastrelid, ct.relfilenode AS toast_relfilenode, i.indexrelid, cti.relfilenode AS toast_index_relfilenode "
                               5422                 :                :                       "FROM pg_catalog.pg_class c LEFT JOIN "
                               5423                 :                :                       "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
                               5424                 :                :                       "LEFT JOIN pg_catalog.pg_class ct ON (c.reltoastrelid = ct.oid) "
                               5425                 :                :                       "LEFT JOIN pg_catalog.pg_class AS cti ON (i.indexrelid = cti.oid) "
                               5426                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid;",
                               5427                 :                :                       pg_class_oid);
                               5428                 :                : 
                               5429                 :           1119 :     upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
                               5430                 :                : 
                               5431                 :           1119 :     relkind = *PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "relkind"));
                               5432                 :                : 
  564                          5433                 :           1119 :     relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
                               5434                 :                :                                       PQfnumber(upgrade_res, "relfilenode")));
  818                          5435                 :           1119 :     toast_oid = atooid(PQgetvalue(upgrade_res, 0,
                               5436                 :                :                                   PQfnumber(upgrade_res, "reltoastrelid")));
  564                          5437                 :           1119 :     toast_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
                               5438                 :                :                                             PQfnumber(upgrade_res, "toast_relfilenode")));
  818                          5439                 :           1119 :     toast_index_oid = atooid(PQgetvalue(upgrade_res, 0,
                               5440                 :                :                                         PQfnumber(upgrade_res, "indexrelid")));
  564                          5441                 :           1119 :     toast_index_relfilenumber = atooid(PQgetvalue(upgrade_res, 0,
                               5442                 :                :                                                   PQfnumber(upgrade_res, "toast_index_relfilenode")));
                               5443                 :                : 
 3800 heikki.linnakangas@i     5444                 :           1119 :     appendPQExpBufferStr(upgrade_buffer,
                               5445                 :                :                          "\n-- For binary upgrade, must preserve pg_class oids and relfilenodes\n");
                               5446                 :                : 
 5212 bruce@momjian.us         5447         [ +  + ]:           1119 :     if (!is_index)
                               5448                 :                :     {
                               5449                 :            836 :         appendPQExpBuffer(upgrade_buffer,
                               5450                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_heap_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5451                 :                :                           pg_class_oid);
                               5452                 :                : 
                               5453                 :                :         /*
                               5454                 :                :          * Not every relation has storage. Also, in a pre-v12 database,
                               5455                 :                :          * partitioned tables have a relfilenumber, which should not be
                               5456                 :                :          * preserved when upgrading.
                               5457                 :                :          */
  648 rhaas@postgresql.org     5458   [ +  +  +  - ]:            836 :         if (RelFileNumberIsValid(relfilenumber) && relkind != RELKIND_PARTITIONED_TABLE)
  818                          5459                 :            686 :             appendPQExpBuffer(upgrade_buffer,
                               5460                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_heap_relfilenode('%u'::pg_catalog.oid);\n",
                               5461                 :                :                               relfilenumber);
                               5462                 :                : 
                               5463                 :                :         /*
                               5464                 :                :          * In a pre-v12 database, partitioned tables might be marked as having
                               5465                 :                :          * toast tables, but we should ignore them if so.
                               5466                 :                :          */
                               5467   [ +  +  +  - ]:            836 :         if (OidIsValid(toast_oid) &&
                               5468                 :                :             relkind != RELKIND_PARTITIONED_TABLE)
                               5469                 :                :         {
 4848 bruce@momjian.us         5470                 :            272 :             appendPQExpBuffer(upgrade_buffer,
                               5471                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5472                 :                :                               toast_oid);
  818 rhaas@postgresql.org     5473                 :            272 :             appendPQExpBuffer(upgrade_buffer,
                               5474                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_toast_relfilenode('%u'::pg_catalog.oid);\n",
                               5475                 :                :                               toast_relfilenumber);
                               5476                 :                : 
                               5477                 :                :             /* every toast table has an index */
 4848 bruce@momjian.us         5478                 :            272 :             appendPQExpBuffer(upgrade_buffer,
                               5479                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5480                 :                :                               toast_index_oid);
  818 rhaas@postgresql.org     5481                 :            272 :             appendPQExpBuffer(upgrade_buffer,
                               5482                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5483                 :                :                               toast_index_relfilenumber);
                               5484                 :                :         }
                               5485                 :                : 
 1377 tgl@sss.pgh.pa.us        5486                 :            836 :         PQclear(upgrade_res);
                               5487                 :                :     }
                               5488                 :                :     else
                               5489                 :                :     {
                               5490                 :                :         /* Preserve the OID and relfilenumber of the index */
 5212 bruce@momjian.us         5491                 :            283 :         appendPQExpBuffer(upgrade_buffer,
                               5492                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                               5493                 :                :                           pg_class_oid);
  818 rhaas@postgresql.org     5494                 :            283 :         appendPQExpBuffer(upgrade_buffer,
                               5495                 :                :                           "SELECT pg_catalog.binary_upgrade_set_next_index_relfilenode('%u'::pg_catalog.oid);\n",
                               5496                 :                :                           relfilenumber);
                               5497                 :                :     }
                               5498                 :                : 
 3800 heikki.linnakangas@i     5499                 :           1119 :     appendPQExpBufferChar(upgrade_buffer, '\n');
                               5500                 :                : 
  812 tgl@sss.pgh.pa.us        5501                 :           1119 :     destroyPQExpBuffer(upgrade_query);
 5225 bruce@momjian.us         5502                 :           1119 : }
                               5503                 :                : 
                               5504                 :                : /*
                               5505                 :                :  * If the DumpableObject is a member of an extension, add a suitable
                               5506                 :                :  * ALTER EXTENSION ADD command to the creation commands in upgrade_buffer.
                               5507                 :                :  *
                               5508                 :                :  * For somewhat historical reasons, objname should already be quoted,
                               5509                 :                :  * but not objnamespace (if any).
                               5510                 :                :  */
                               5511                 :                : static void
 4813 tgl@sss.pgh.pa.us        5512                 :           1318 : binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                               5513                 :                :                                 const DumpableObject *dobj,
                               5514                 :                :                                 const char *objtype,
                               5515                 :                :                                 const char *objname,
                               5516                 :                :                                 const char *objnamespace)
                               5517                 :                : {
                               5518                 :           1318 :     DumpableObject *extobj = NULL;
                               5519                 :                :     int         i;
                               5520                 :                : 
                               5521         [ +  + ]:           1318 :     if (!dobj->ext_member)
                               5522                 :           1302 :         return;
                               5523                 :                : 
                               5524                 :                :     /*
                               5525                 :                :      * Find the parent extension.  We could avoid this search if we wanted to
                               5526                 :                :      * add a link field to DumpableObject, but the space costs of that would
                               5527                 :                :      * be considerable.  We assume that member objects could only have a
                               5528                 :                :      * direct dependency on their own extension, not any others.
                               5529                 :                :      */
                               5530         [ +  - ]:             16 :     for (i = 0; i < dobj->nDeps; i++)
                               5531                 :                :     {
                               5532                 :             16 :         extobj = findObjectByDumpId(dobj->dependencies[i]);
                               5533   [ +  -  +  - ]:             16 :         if (extobj && extobj->objType == DO_EXTENSION)
                               5534                 :             16 :             break;
 4813 tgl@sss.pgh.pa.us        5535                 :UBC           0 :         extobj = NULL;
                               5536                 :                :     }
 4813 tgl@sss.pgh.pa.us        5537         [ -  + ]:CBC          16 :     if (extobj == NULL)
  737 tgl@sss.pgh.pa.us        5538                 :UBC           0 :         pg_fatal("could not find parent extension for %s %s",
                               5539                 :                :                  objtype, objname);
                               5540                 :                : 
 3800 heikki.linnakangas@i     5541                 :CBC          16 :     appendPQExpBufferStr(upgrade_buffer,
                               5542                 :                :                          "\n-- For binary upgrade, handle extension membership the hard way\n");
 2239 tgl@sss.pgh.pa.us        5543                 :             16 :     appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s ",
 4813                          5544                 :             16 :                       fmtId(extobj->name),
                               5545                 :                :                       objtype);
 2239                          5546   [ +  +  +  - ]:             16 :     if (objnamespace && *objnamespace)
                               5547                 :             13 :         appendPQExpBuffer(upgrade_buffer, "%s.", fmtId(objnamespace));
                               5548                 :             16 :     appendPQExpBuffer(upgrade_buffer, "%s;\n", objname);
                               5549                 :                : }
                               5550                 :                : 
                               5551                 :                : /*
                               5552                 :                :  * getNamespaces:
                               5553                 :                :  *    read all namespaces in the system catalogs and return them in the
                               5554                 :                :  * NamespaceInfo* structure
                               5555                 :                :  *
                               5556                 :                :  *  numNamespaces is set to the number of namespaces read in
                               5557                 :                :  */
                               5558                 :                : NamespaceInfo *
 4451 rhaas@postgresql.org     5559                 :            156 : getNamespaces(Archive *fout, int *numNamespaces)
                               5560                 :                : {
                               5561                 :                :     PGresult   *res;
                               5562                 :                :     int         ntups;
                               5563                 :                :     int         i;
                               5564                 :                :     PQExpBuffer query;
                               5565                 :                :     NamespaceInfo *nsinfo;
                               5566                 :                :     int         i_tableoid;
                               5567                 :                :     int         i_oid;
                               5568                 :                :     int         i_nspname;
                               5569                 :                :     int         i_nspowner;
                               5570                 :                :     int         i_nspacl;
                               5571                 :                :     int         i_acldefault;
                               5572                 :                : 
 8010 tgl@sss.pgh.pa.us        5573                 :            156 :     query = createPQExpBuffer();
                               5574                 :                : 
                               5575                 :                :     /*
                               5576                 :                :      * we fetch all namespaces including system ones, so that every object we
                               5577                 :                :      * read in can be linked to a containing namespace.
                               5578                 :                :      */
  586 drowley@postgresql.o     5579                 :            156 :     appendPQExpBufferStr(query, "SELECT n.tableoid, n.oid, n.nspname, "
                               5580                 :                :                          "n.nspowner, "
                               5581                 :                :                          "n.nspacl, "
                               5582                 :                :                          "acldefault('n', n.nspowner) AS acldefault "
                               5583                 :                :                          "FROM pg_namespace n");
                               5584                 :                : 
 4450 rhaas@postgresql.org     5585                 :            156 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5586                 :                : 
 9716 bruce@momjian.us         5587                 :            156 :     ntups = PQntuples(res);
                               5588                 :                : 
 4524                          5589                 :            156 :     nsinfo = (NamespaceInfo *) pg_malloc(ntups * sizeof(NamespaceInfo));
                               5590                 :                : 
 7435 tgl@sss.pgh.pa.us        5591                 :            156 :     i_tableoid = PQfnumber(res, "tableoid");
 9716 bruce@momjian.us         5592                 :            156 :     i_oid = PQfnumber(res, "oid");
 8010 tgl@sss.pgh.pa.us        5593                 :            156 :     i_nspname = PQfnumber(res, "nspname");
 1021 noah@leadboat.com        5594                 :            156 :     i_nspowner = PQfnumber(res, "nspowner");
 8010 tgl@sss.pgh.pa.us        5595                 :            156 :     i_nspacl = PQfnumber(res, "nspacl");
  860                          5596                 :            156 :     i_acldefault = PQfnumber(res, "acldefault");
                               5597                 :                : 
 9716 bruce@momjian.us         5598         [ +  + ]:           1308 :     for (i = 0; i < ntups; i++)
                               5599                 :                :     {
                               5600                 :                :         const char *nspowner;
                               5601                 :                : 
 7435 tgl@sss.pgh.pa.us        5602                 :           1152 :         nsinfo[i].dobj.objType = DO_NAMESPACE;
                               5603                 :           1152 :         nsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               5604                 :           1152 :         nsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5605                 :           1152 :         AssignDumpId(&nsinfo[i].dobj);
 4524 bruce@momjian.us         5606                 :           1152 :         nsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_nspname));
  860 tgl@sss.pgh.pa.us        5607                 :           1152 :         nsinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_nspacl));
                               5608                 :           1152 :         nsinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               5609                 :           1152 :         nsinfo[i].dacl.privtype = 0;
                               5610                 :           1152 :         nsinfo[i].dacl.initprivs = NULL;
  835                          5611                 :           1152 :         nspowner = PQgetvalue(res, i, i_nspowner);
                               5612                 :           1152 :         nsinfo[i].nspowner = atooid(nspowner);
                               5613                 :           1152 :         nsinfo[i].rolname = getRoleName(nspowner);
                               5614                 :                : 
                               5615                 :                :         /* Decide whether to dump this namespace */
 2930 sfrost@snowman.net       5616                 :           1152 :         selectDumpableNamespace(&nsinfo[i], fout);
                               5617                 :                : 
                               5618                 :                :         /* Mark whether namespace has an ACL */
  860 tgl@sss.pgh.pa.us        5619         [ +  + ]:           1152 :         if (!PQgetisnull(res, i, i_nspacl))
                               5620                 :            515 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               5621                 :                : 
                               5622                 :                :         /*
                               5623                 :                :          * We ignore any pg_init_privs.initprivs entry for the public schema
                               5624                 :                :          * and assume a predetermined default, for several reasons.  First,
                               5625                 :                :          * dropping and recreating the schema removes its pg_init_privs entry,
                               5626                 :                :          * but an empty destination database starts with this ACL nonetheless.
                               5627                 :                :          * Second, we support dump/reload of public schema ownership changes.
                               5628                 :                :          * ALTER SCHEMA OWNER filters nspacl through aclnewowner(), but
                               5629                 :                :          * initprivs continues to reflect the initial owner.  Hence,
                               5630                 :                :          * synthesize the value that nspacl will have after the restore's
                               5631                 :                :          * ALTER SCHEMA OWNER.  Third, this makes the destination database
                               5632                 :                :          * match the source's ACL, even if the latter was an initdb-default
                               5633                 :                :          * ACL, which changed in v15.  An upgrade pulls in changes to most
                               5634                 :                :          * system object ACLs that the DBA had not customized.  We've made the
                               5635                 :                :          * public schema depart from that, because changing its ACL so easily
                               5636                 :                :          * breaks applications.
                               5637                 :                :          */
                               5638         [ +  + ]:           1152 :         if (strcmp(nsinfo[i].dobj.name, "public") == 0)
                               5639                 :                :         {
                               5640                 :            152 :             PQExpBuffer aclarray = createPQExpBuffer();
                               5641                 :            152 :             PQExpBuffer aclitem = createPQExpBuffer();
                               5642                 :                : 
                               5643                 :                :             /* Standard ACL as of v15 is {owner=UC/owner,=U/owner} */
                               5644                 :            152 :             appendPQExpBufferChar(aclarray, '{');
                               5645                 :            152 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               5646                 :            152 :             appendPQExpBufferStr(aclitem, "=UC/");
                               5647                 :            152 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               5648                 :            152 :             appendPGArray(aclarray, aclitem->data);
                               5649                 :            152 :             resetPQExpBuffer(aclitem);
                               5650                 :            152 :             appendPQExpBufferStr(aclitem, "=U/");
                               5651                 :            152 :             quoteAclUserName(aclitem, nsinfo[i].rolname);
                               5652                 :            152 :             appendPGArray(aclarray, aclitem->data);
                               5653                 :            152 :             appendPQExpBufferChar(aclarray, '}');
                               5654                 :                : 
                               5655                 :            152 :             nsinfo[i].dacl.privtype = 'i';
                               5656                 :            152 :             nsinfo[i].dacl.initprivs = pstrdup(aclarray->data);
                               5657                 :            152 :             nsinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               5658                 :                : 
                               5659                 :            152 :             destroyPQExpBuffer(aclarray);
                               5660                 :            152 :             destroyPQExpBuffer(aclitem);
                               5661                 :                :         }
                               5662                 :                :     }
                               5663                 :                : 
 9716 bruce@momjian.us         5664                 :            156 :     PQclear(res);
 8290 tgl@sss.pgh.pa.us        5665                 :            156 :     destroyPQExpBuffer(query);
                               5666                 :                : 
 4342                          5667                 :            156 :     *numNamespaces = ntups;
                               5668                 :                : 
 8010                          5669                 :            156 :     return nsinfo;
                               5670                 :                : }
                               5671                 :                : 
                               5672                 :                : /*
                               5673                 :                :  * findNamespace:
                               5674                 :                :  *      given a namespace OID, look up the info read by getNamespaces
                               5675                 :                :  */
                               5676                 :                : static NamespaceInfo *
 1328 peter@eisentraut.org     5677                 :         583561 : findNamespace(Oid nsoid)
                               5678                 :                : {
                               5679                 :                :     NamespaceInfo *nsinfo;
                               5680                 :                : 
 2741 tgl@sss.pgh.pa.us        5681                 :         583561 :     nsinfo = findNamespaceByOid(nsoid);
 4342                          5682         [ -  + ]:         583561 :     if (nsinfo == NULL)
  737 tgl@sss.pgh.pa.us        5683                 :UBC           0 :         pg_fatal("schema with OID %u does not exist", nsoid);
 4342 tgl@sss.pgh.pa.us        5684                 :CBC      583561 :     return nsinfo;
                               5685                 :                : }
                               5686                 :                : 
                               5687                 :                : /*
                               5688                 :                :  * getExtensions:
                               5689                 :                :  *    read all extensions in the system catalogs and return them in the
                               5690                 :                :  * ExtensionInfo* structure
                               5691                 :                :  *
                               5692                 :                :  *  numExtensions is set to the number of extensions read in
                               5693                 :                :  */
                               5694                 :                : ExtensionInfo *
 3014                          5695                 :            156 : getExtensions(Archive *fout, int *numExtensions)
                               5696                 :                : {
                               5697                 :            156 :     DumpOptions *dopt = fout->dopt;
                               5698                 :                :     PGresult   *res;
                               5699                 :                :     int         ntups;
                               5700                 :                :     int         i;
                               5701                 :                :     PQExpBuffer query;
                               5702                 :                :     ExtensionInfo *extinfo;
                               5703                 :                :     int         i_tableoid;
                               5704                 :                :     int         i_oid;
                               5705                 :                :     int         i_extname;
                               5706                 :                :     int         i_nspname;
                               5707                 :                :     int         i_extrelocatable;
                               5708                 :                :     int         i_extversion;
                               5709                 :                :     int         i_extconfig;
                               5710                 :                :     int         i_extcondition;
                               5711                 :                : 
 4814                          5712                 :            156 :     query = createPQExpBuffer();
                               5713                 :                : 
 3800 heikki.linnakangas@i     5714                 :            156 :     appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
                               5715                 :                :                          "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
                               5716                 :                :                          "FROM pg_extension x "
                               5717                 :                :                          "JOIN pg_namespace n ON n.oid = x.extnamespace");
                               5718                 :                : 
 4450 rhaas@postgresql.org     5719                 :            156 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5720                 :                : 
 4814 tgl@sss.pgh.pa.us        5721                 :            156 :     ntups = PQntuples(res);
                               5722                 :                : 
 4524 bruce@momjian.us         5723                 :            156 :     extinfo = (ExtensionInfo *) pg_malloc(ntups * sizeof(ExtensionInfo));
                               5724                 :                : 
 4814 tgl@sss.pgh.pa.us        5725                 :            156 :     i_tableoid = PQfnumber(res, "tableoid");
                               5726                 :            156 :     i_oid = PQfnumber(res, "oid");
                               5727                 :            156 :     i_extname = PQfnumber(res, "extname");
                               5728                 :            156 :     i_nspname = PQfnumber(res, "nspname");
 4813                          5729                 :            156 :     i_extrelocatable = PQfnumber(res, "extrelocatable");
                               5730                 :            156 :     i_extversion = PQfnumber(res, "extversion");
 4814                          5731                 :            156 :     i_extconfig = PQfnumber(res, "extconfig");
                               5732                 :            156 :     i_extcondition = PQfnumber(res, "extcondition");
                               5733                 :                : 
                               5734         [ +  + ]:            337 :     for (i = 0; i < ntups; i++)
                               5735                 :                :     {
                               5736                 :            181 :         extinfo[i].dobj.objType = DO_EXTENSION;
                               5737                 :            181 :         extinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               5738                 :            181 :         extinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5739                 :            181 :         AssignDumpId(&extinfo[i].dobj);
 4524 bruce@momjian.us         5740                 :            181 :         extinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_extname));
                               5741                 :            181 :         extinfo[i].namespace = pg_strdup(PQgetvalue(res, i, i_nspname));
 4813 tgl@sss.pgh.pa.us        5742                 :            181 :         extinfo[i].relocatable = *(PQgetvalue(res, i, i_extrelocatable)) == 't';
 4524 bruce@momjian.us         5743                 :            181 :         extinfo[i].extversion = pg_strdup(PQgetvalue(res, i, i_extversion));
                               5744                 :            181 :         extinfo[i].extconfig = pg_strdup(PQgetvalue(res, i, i_extconfig));
                               5745                 :            181 :         extinfo[i].extcondition = pg_strdup(PQgetvalue(res, i, i_extcondition));
                               5746                 :                : 
                               5747                 :                :         /* Decide whether we want to dump it */
 3014 tgl@sss.pgh.pa.us        5748                 :            181 :         selectDumpableExtension(&(extinfo[i]), dopt);
                               5749                 :                :     }
                               5750                 :                : 
 4814                          5751                 :            156 :     PQclear(res);
                               5752                 :            156 :     destroyPQExpBuffer(query);
                               5753                 :                : 
                               5754                 :            156 :     *numExtensions = ntups;
                               5755                 :                : 
                               5756                 :            156 :     return extinfo;
                               5757                 :                : }
                               5758                 :                : 
                               5759                 :                : /*
                               5760                 :                :  * getTypes:
                               5761                 :                :  *    read all types in the system catalogs and return them in the
                               5762                 :                :  * TypeInfo* structure
                               5763                 :                :  *
                               5764                 :                :  *  numTypes is set to the number of types read in
                               5765                 :                :  *
                               5766                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               5767                 :                :  * findFuncByOid().
                               5768                 :                :  */
                               5769                 :                : TypeInfo *
 4451 rhaas@postgresql.org     5770                 :            155 : getTypes(Archive *fout, int *numTypes)
                               5771                 :                : {
                               5772                 :                :     PGresult   *res;
                               5773                 :                :     int         ntups;
                               5774                 :                :     int         i;
 8768 bruce@momjian.us         5775                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               5776                 :                :     TypeInfo   *tyinfo;
                               5777                 :                :     ShellTypeInfo *stinfo;
                               5778                 :                :     int         i_tableoid;
                               5779                 :                :     int         i_oid;
                               5780                 :                :     int         i_typname;
                               5781                 :                :     int         i_typnamespace;
                               5782                 :                :     int         i_typacl;
                               5783                 :                :     int         i_acldefault;
                               5784                 :                :     int         i_typowner;
                               5785                 :                :     int         i_typelem;
                               5786                 :                :     int         i_typrelid;
                               5787                 :                :     int         i_typrelkind;
                               5788                 :                :     int         i_typtype;
                               5789                 :                :     int         i_typisdefined;
                               5790                 :                :     int         i_isarray;
                               5791                 :                : 
                               5792                 :                :     /*
                               5793                 :                :      * we include even the built-in types because those may be used as array
                               5794                 :                :      * elements by user-defined types
                               5795                 :                :      *
                               5796                 :                :      * we filter out the built-in types when we dump out the types
                               5797                 :                :      *
                               5798                 :                :      * same approach for undefined (shell) types and array types
                               5799                 :                :      *
                               5800                 :                :      * Note: as of 8.3 we can reliably detect whether a type is an
                               5801                 :                :      * auto-generated array type by checking the element type's typarray.
                               5802                 :                :      * (Before that the test is capable of generating false positives.) We
                               5803                 :                :      * still check for name beginning with '_', though, so as to avoid the
                               5804                 :                :      * cost of the subselect probe for all standard types.  This would have to
                               5805                 :                :      * be revisited if the backend ever allows renaming of array types.
                               5806                 :                :      */
  586 drowley@postgresql.o     5807                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, typname, "
                               5808                 :                :                          "typnamespace, typacl, "
                               5809                 :                :                          "acldefault('T', typowner) AS acldefault, "
                               5810                 :                :                          "typowner, "
                               5811                 :                :                          "typelem, typrelid, "
                               5812                 :                :                          "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
                               5813                 :                :                          "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
                               5814                 :                :                          "typtype, typisdefined, "
                               5815                 :                :                          "typname[0] = '_' AND typelem != 0 AND "
                               5816                 :                :                          "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
                               5817                 :                :                          "FROM pg_type");
                               5818                 :                : 
 4450 rhaas@postgresql.org     5819                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5820                 :                : 
 9716 bruce@momjian.us         5821                 :            155 :     ntups = PQntuples(res);
                               5822                 :                : 
 4524                          5823                 :            155 :     tyinfo = (TypeInfo *) pg_malloc(ntups * sizeof(TypeInfo));
                               5824                 :                : 
 7435 tgl@sss.pgh.pa.us        5825                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 9716 bruce@momjian.us         5826                 :            155 :     i_oid = PQfnumber(res, "oid");
 8010 tgl@sss.pgh.pa.us        5827                 :            155 :     i_typname = PQfnumber(res, "typname");
                               5828                 :            155 :     i_typnamespace = PQfnumber(res, "typnamespace");
 4144                          5829                 :            155 :     i_typacl = PQfnumber(res, "typacl");
  860                          5830                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
  835                          5831                 :            155 :     i_typowner = PQfnumber(res, "typowner");
 8010                          5832                 :            155 :     i_typelem = PQfnumber(res, "typelem");
                               5833                 :            155 :     i_typrelid = PQfnumber(res, "typrelid");
 7913 bruce@momjian.us         5834                 :            155 :     i_typrelkind = PQfnumber(res, "typrelkind");
 8010 tgl@sss.pgh.pa.us        5835                 :            155 :     i_typtype = PQfnumber(res, "typtype");
                               5836                 :            155 :     i_typisdefined = PQfnumber(res, "typisdefined");
 6183                          5837                 :            155 :     i_isarray = PQfnumber(res, "isarray");
                               5838                 :                : 
 9716 bruce@momjian.us         5839         [ +  + ]:         108957 :     for (i = 0; i < ntups; i++)
                               5840                 :                :     {
 5226                          5841                 :         108802 :         tyinfo[i].dobj.objType = DO_TYPE;
                               5842                 :         108802 :         tyinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               5843                 :         108802 :         tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5844                 :         108802 :         AssignDumpId(&tyinfo[i].dobj);
 4524                          5845                 :         108802 :         tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
 4451 rhaas@postgresql.org     5846                 :         217604 :         tyinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     5847                 :         108802 :             findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)));
  860 tgl@sss.pgh.pa.us        5848                 :         108802 :         tyinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_typacl));
                               5849                 :         108802 :         tyinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               5850                 :         108802 :         tyinfo[i].dacl.privtype = 0;
                               5851                 :         108802 :         tyinfo[i].dacl.initprivs = NULL;
  957                          5852                 :         108802 :         tyinfo[i].ftypname = NULL;  /* may get filled later */
  835                          5853                 :         108802 :         tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner));
 5226 bruce@momjian.us         5854                 :         108802 :         tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
                               5855                 :         108802 :         tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
                               5856                 :         108802 :         tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
                               5857                 :         108802 :         tyinfo[i].typtype = *PQgetvalue(res, i, i_typtype);
                               5858                 :         108802 :         tyinfo[i].shellType = NULL;
                               5859                 :                : 
 8010 tgl@sss.pgh.pa.us        5860         [ +  + ]:         108802 :         if (strcmp(PQgetvalue(res, i, i_typisdefined), "t") == 0)
 5226 bruce@momjian.us         5861                 :         108751 :             tyinfo[i].isDefined = true;
                               5862                 :                :         else
                               5863                 :             51 :             tyinfo[i].isDefined = false;
                               5864                 :                : 
 6183 tgl@sss.pgh.pa.us        5865         [ +  + ]:         108802 :         if (strcmp(PQgetvalue(res, i, i_isarray), "t") == 0)
 5226 bruce@momjian.us         5866                 :          52128 :             tyinfo[i].isArray = true;
                               5867                 :                :         else
                               5868                 :          56674 :             tyinfo[i].isArray = false;
                               5869                 :                : 
   60 tgl@sss.pgh.pa.us        5870         [ +  + ]:GNC      108802 :         if (tyinfo[i].typtype == TYPTYPE_MULTIRANGE)
 1211 akorotkov@postgresql     5871                 :CBC        1042 :             tyinfo[i].isMultirange = true;
                               5872                 :                :         else
                               5873                 :         107760 :             tyinfo[i].isMultirange = false;
                               5874                 :                : 
                               5875                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       5876                 :         108802 :         selectDumpableType(&tyinfo[i], fout);
                               5877                 :                : 
                               5878                 :                :         /* Mark whether type has an ACL */
  860 tgl@sss.pgh.pa.us        5879         [ +  + ]:         108802 :         if (!PQgetisnull(res, i, i_typacl))
                               5880                 :            209 :             tyinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               5881                 :                : 
                               5882                 :                :         /*
                               5883                 :                :          * If it's a domain, fetch info about its constraints, if any
                               5884                 :                :          */
 5226 bruce@momjian.us         5885                 :         108802 :         tyinfo[i].nDomChecks = 0;
                               5886                 :         108802 :         tyinfo[i].domChecks = NULL;
 2930 sfrost@snowman.net       5887         [ +  + ]:         108802 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               5888         [ +  + ]:          12510 :             tyinfo[i].typtype == TYPTYPE_DOMAIN)
 4451 rhaas@postgresql.org     5889                 :            134 :             getDomainConstraints(fout, &(tyinfo[i]));
                               5890                 :                : 
                               5891                 :                :         /*
                               5892                 :                :          * If it's a base type, make a DumpableObject representing a shell
                               5893                 :                :          * definition of the type.  We will need to dump that ahead of the I/O
                               5894                 :                :          * functions for the type.  Similarly, range types need a shell
                               5895                 :                :          * definition in case they have a canonicalize function.
                               5896                 :                :          *
                               5897                 :                :          * Note: the shell type doesn't have a catId.  You might think it
                               5898                 :                :          * should copy the base type's catId, but then it might capture the
                               5899                 :                :          * pg_depend entries for the type, which we don't want.
                               5900                 :                :          */
 2930 sfrost@snowman.net       5901         [ +  + ]:         108802 :         if ((tyinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                               5902         [ +  + ]:          12510 :             (tyinfo[i].typtype == TYPTYPE_BASE ||
                               5903         [ +  + ]:           6153 :              tyinfo[i].typtype == TYPTYPE_RANGE))
                               5904                 :                :         {
 4524 bruce@momjian.us         5905                 :           6461 :             stinfo = (ShellTypeInfo *) pg_malloc(sizeof(ShellTypeInfo));
 6618 tgl@sss.pgh.pa.us        5906                 :           6461 :             stinfo->dobj.objType = DO_SHELL_TYPE;
                               5907                 :           6461 :             stinfo->dobj.catId = nilCatalogId;
                               5908                 :           6461 :             AssignDumpId(&stinfo->dobj);
 4524 bruce@momjian.us         5909                 :           6461 :             stinfo->dobj.name = pg_strdup(tyinfo[i].dobj.name);
 5226                          5910                 :           6461 :             stinfo->dobj.namespace = tyinfo[i].dobj.namespace;
                               5911                 :           6461 :             stinfo->baseType = &(tyinfo[i]);
                               5912                 :           6461 :             tyinfo[i].shellType = stinfo;
                               5913                 :                : 
                               5914                 :                :             /*
                               5915                 :                :              * Initially mark the shell type as not to be dumped.  We'll only
                               5916                 :                :              * dump it if the I/O or canonicalize functions need to be dumped;
                               5917                 :                :              * this is taken care of while sorting dependencies.
                               5918                 :                :              */
 2930 sfrost@snowman.net       5919                 :           6461 :             stinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               5920                 :                :         }
                               5921                 :                :     }
                               5922                 :                : 
 8010 tgl@sss.pgh.pa.us        5923                 :            155 :     *numTypes = ntups;
                               5924                 :                : 
 9716 bruce@momjian.us         5925                 :            155 :     PQclear(res);
                               5926                 :                : 
 8290 tgl@sss.pgh.pa.us        5927                 :            155 :     destroyPQExpBuffer(query);
                               5928                 :                : 
 5226 bruce@momjian.us         5929                 :            155 :     return tyinfo;
                               5930                 :                : }
                               5931                 :                : 
                               5932                 :                : /*
                               5933                 :                :  * getOperators:
                               5934                 :                :  *    read all operators in the system catalogs and return them in the
                               5935                 :                :  * OprInfo* structure
                               5936                 :                :  *
                               5937                 :                :  *  numOprs is set to the number of operators read in
                               5938                 :                :  */
                               5939                 :                : OprInfo *
 4451 rhaas@postgresql.org     5940                 :            155 : getOperators(Archive *fout, int *numOprs)
                               5941                 :                : {
                               5942                 :                :     PGresult   *res;
                               5943                 :                :     int         ntups;
                               5944                 :                :     int         i;
 8768 bruce@momjian.us         5945                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               5946                 :                :     OprInfo    *oprinfo;
                               5947                 :                :     int         i_tableoid;
                               5948                 :                :     int         i_oid;
                               5949                 :                :     int         i_oprname;
                               5950                 :                :     int         i_oprnamespace;
                               5951                 :                :     int         i_oprowner;
                               5952                 :                :     int         i_oprkind;
                               5953                 :                :     int         i_oprcode;
                               5954                 :                : 
                               5955                 :                :     /*
                               5956                 :                :      * find all operators, including builtin operators; we filter out
                               5957                 :                :      * system-defined operators at dump-out time.
                               5958                 :                :      */
                               5959                 :                : 
  586 drowley@postgresql.o     5960                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, oprname, "
                               5961                 :                :                          "oprnamespace, "
                               5962                 :                :                          "oprowner, "
                               5963                 :                :                          "oprkind, "
                               5964                 :                :                          "oprcode::oid AS oprcode "
                               5965                 :                :                          "FROM pg_operator");
                               5966                 :                : 
 4450 rhaas@postgresql.org     5967                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               5968                 :                : 
 9716 bruce@momjian.us         5969                 :            155 :     ntups = PQntuples(res);
 8010 tgl@sss.pgh.pa.us        5970                 :            155 :     *numOprs = ntups;
                               5971                 :                : 
 4524 bruce@momjian.us         5972                 :            155 :     oprinfo = (OprInfo *) pg_malloc(ntups * sizeof(OprInfo));
                               5973                 :                : 
 7435 tgl@sss.pgh.pa.us        5974                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 9716 bruce@momjian.us         5975                 :            155 :     i_oid = PQfnumber(res, "oid");
 8010 tgl@sss.pgh.pa.us        5976                 :            155 :     i_oprname = PQfnumber(res, "oprname");
                               5977                 :            155 :     i_oprnamespace = PQfnumber(res, "oprnamespace");
  835                          5978                 :            155 :     i_oprowner = PQfnumber(res, "oprowner");
 4483 peter_e@gmx.net          5979                 :            155 :     i_oprkind = PQfnumber(res, "oprkind");
 8010 tgl@sss.pgh.pa.us        5980                 :            155 :     i_oprcode = PQfnumber(res, "oprcode");
                               5981                 :                : 
 9716 bruce@momjian.us         5982         [ +  + ]:         124115 :     for (i = 0; i < ntups; i++)
                               5983                 :                :     {
 7435 tgl@sss.pgh.pa.us        5984                 :         123960 :         oprinfo[i].dobj.objType = DO_OPERATOR;
                               5985                 :         123960 :         oprinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               5986                 :         123960 :         oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               5987                 :         123960 :         AssignDumpId(&oprinfo[i].dobj);
 4524 bruce@momjian.us         5988                 :         123960 :         oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
 4451 rhaas@postgresql.org     5989                 :         247920 :         oprinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     5990                 :         123960 :             findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)));
  835 tgl@sss.pgh.pa.us        5991                 :         123960 :         oprinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_oprowner));
 4483 peter_e@gmx.net          5992                 :         123960 :         oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
 7435 tgl@sss.pgh.pa.us        5993                 :         123960 :         oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
                               5994                 :                : 
                               5995                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       5996                 :         123960 :         selectDumpableObject(&(oprinfo[i].dobj), fout);
                               5997                 :                :     }
                               5998                 :                : 
 9716 bruce@momjian.us         5999                 :            155 :     PQclear(res);
                               6000                 :                : 
 8290 tgl@sss.pgh.pa.us        6001                 :            155 :     destroyPQExpBuffer(query);
                               6002                 :                : 
 8010                          6003                 :            155 :     return oprinfo;
                               6004                 :                : }
                               6005                 :                : 
                               6006                 :                : /*
                               6007                 :                :  * getCollations:
                               6008                 :                :  *    read all collations in the system catalogs and return them in the
                               6009                 :                :  * CollInfo* structure
                               6010                 :                :  *
                               6011                 :                :  *  numCollations is set to the number of collations read in
                               6012                 :                :  */
                               6013                 :                : CollInfo *
 4451 rhaas@postgresql.org     6014                 :            155 : getCollations(Archive *fout, int *numCollations)
                               6015                 :                : {
                               6016                 :                :     PGresult   *res;
                               6017                 :                :     int         ntups;
                               6018                 :                :     int         i;
                               6019                 :                :     PQExpBuffer query;
                               6020                 :                :     CollInfo   *collinfo;
                               6021                 :                :     int         i_tableoid;
                               6022                 :                :     int         i_oid;
                               6023                 :                :     int         i_collname;
                               6024                 :                :     int         i_collnamespace;
                               6025                 :                :     int         i_collowner;
                               6026                 :                : 
 4415 peter_e@gmx.net          6027                 :            155 :     query = createPQExpBuffer();
                               6028                 :                : 
                               6029                 :                :     /*
                               6030                 :                :      * find all collations, including builtin collations; we filter out
                               6031                 :                :      * system-defined collations at dump-out time.
                               6032                 :                :      */
                               6033                 :                : 
  586 drowley@postgresql.o     6034                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, collname, "
                               6035                 :                :                          "collnamespace, "
                               6036                 :                :                          "collowner "
                               6037                 :                :                          "FROM pg_collation");
                               6038                 :                : 
 4450 rhaas@postgresql.org     6039                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6040                 :                : 
 4810 peter_e@gmx.net          6041                 :            155 :     ntups = PQntuples(res);
                               6042                 :            155 :     *numCollations = ntups;
                               6043                 :                : 
 4524 bruce@momjian.us         6044                 :            155 :     collinfo = (CollInfo *) pg_malloc(ntups * sizeof(CollInfo));
                               6045                 :                : 
 4810 peter_e@gmx.net          6046                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               6047                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6048                 :            155 :     i_collname = PQfnumber(res, "collname");
                               6049                 :            155 :     i_collnamespace = PQfnumber(res, "collnamespace");
  835 tgl@sss.pgh.pa.us        6050                 :            155 :     i_collowner = PQfnumber(res, "collowner");
                               6051                 :                : 
 4810 peter_e@gmx.net          6052         [ +  + ]:         226712 :     for (i = 0; i < ntups; i++)
                               6053                 :                :     {
                               6054                 :         226557 :         collinfo[i].dobj.objType = DO_COLLATION;
                               6055                 :         226557 :         collinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6056                 :         226557 :         collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6057                 :         226557 :         AssignDumpId(&collinfo[i].dobj);
 4524 bruce@momjian.us         6058                 :         226557 :         collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
 4451 rhaas@postgresql.org     6059                 :         453114 :         collinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6060                 :         226557 :             findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)));
  835 tgl@sss.pgh.pa.us        6061                 :         226557 :         collinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_collowner));
                               6062                 :                : 
                               6063                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6064                 :         226557 :         selectDumpableObject(&(collinfo[i].dobj), fout);
                               6065                 :                :     }
                               6066                 :                : 
 4810 peter_e@gmx.net          6067                 :            155 :     PQclear(res);
                               6068                 :                : 
                               6069                 :            155 :     destroyPQExpBuffer(query);
                               6070                 :                : 
                               6071                 :            155 :     return collinfo;
                               6072                 :                : }
                               6073                 :                : 
                               6074                 :                : /*
                               6075                 :                :  * getConversions:
                               6076                 :                :  *    read all conversions in the system catalogs and return them in the
                               6077                 :                :  * ConvInfo* structure
                               6078                 :                :  *
                               6079                 :                :  *  numConversions is set to the number of conversions read in
                               6080                 :                :  */
                               6081                 :                : ConvInfo *
 4451 rhaas@postgresql.org     6082                 :            155 : getConversions(Archive *fout, int *numConversions)
                               6083                 :                : {
                               6084                 :                :     PGresult   *res;
                               6085                 :                :     int         ntups;
                               6086                 :                :     int         i;
                               6087                 :                :     PQExpBuffer query;
                               6088                 :                :     ConvInfo   *convinfo;
                               6089                 :                :     int         i_tableoid;
                               6090                 :                :     int         i_oid;
                               6091                 :                :     int         i_conname;
                               6092                 :                :     int         i_connamespace;
                               6093                 :                :     int         i_conowner;
                               6094                 :                : 
 3731 sfrost@snowman.net       6095                 :            155 :     query = createPQExpBuffer();
                               6096                 :                : 
                               6097                 :                :     /*
                               6098                 :                :      * find all conversions, including builtin conversions; we filter out
                               6099                 :                :      * system-defined conversions at dump-out time.
                               6100                 :                :      */
                               6101                 :                : 
  586 drowley@postgresql.o     6102                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, conname, "
                               6103                 :                :                          "connamespace, "
                               6104                 :                :                          "conowner "
                               6105                 :                :                          "FROM pg_conversion");
                               6106                 :                : 
 4450 rhaas@postgresql.org     6107                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6108                 :                : 
 7450 tgl@sss.pgh.pa.us        6109                 :            155 :     ntups = PQntuples(res);
                               6110                 :            155 :     *numConversions = ntups;
                               6111                 :                : 
 4524 bruce@momjian.us         6112                 :            155 :     convinfo = (ConvInfo *) pg_malloc(ntups * sizeof(ConvInfo));
                               6113                 :                : 
 7435 tgl@sss.pgh.pa.us        6114                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 7450                          6115                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6116                 :            155 :     i_conname = PQfnumber(res, "conname");
                               6117                 :            155 :     i_connamespace = PQfnumber(res, "connamespace");
  835                          6118                 :            155 :     i_conowner = PQfnumber(res, "conowner");
                               6119                 :                : 
 7450                          6120         [ +  + ]:          20041 :     for (i = 0; i < ntups; i++)
                               6121                 :                :     {
 7435                          6122                 :          19886 :         convinfo[i].dobj.objType = DO_CONVERSION;
                               6123                 :          19886 :         convinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6124                 :          19886 :         convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6125                 :          19886 :         AssignDumpId(&convinfo[i].dobj);
 4524 bruce@momjian.us         6126                 :          19886 :         convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 4451 rhaas@postgresql.org     6127                 :          39772 :         convinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6128                 :          19886 :             findNamespace(atooid(PQgetvalue(res, i, i_connamespace)));
  835 tgl@sss.pgh.pa.us        6129                 :          19886 :         convinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_conowner));
                               6130                 :                : 
                               6131                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6132                 :          19886 :         selectDumpableObject(&(convinfo[i].dobj), fout);
                               6133                 :                :     }
                               6134                 :                : 
 7450 tgl@sss.pgh.pa.us        6135                 :            155 :     PQclear(res);
                               6136                 :                : 
                               6137                 :            155 :     destroyPQExpBuffer(query);
                               6138                 :                : 
                               6139                 :            155 :     return convinfo;
                               6140                 :                : }
                               6141                 :                : 
                               6142                 :                : /*
                               6143                 :                :  * getAccessMethods:
                               6144                 :                :  *    read all user-defined access methods in the system catalogs and return
                               6145                 :                :  *    them in the AccessMethodInfo* structure
                               6146                 :                :  *
                               6147                 :                :  *  numAccessMethods is set to the number of access methods read in
                               6148                 :                :  */
                               6149                 :                : AccessMethodInfo *
 2944 alvherre@alvh.no-ip.     6150                 :            155 : getAccessMethods(Archive *fout, int *numAccessMethods)
                               6151                 :                : {
                               6152                 :                :     PGresult   *res;
                               6153                 :                :     int         ntups;
                               6154                 :                :     int         i;
                               6155                 :                :     PQExpBuffer query;
                               6156                 :                :     AccessMethodInfo *aminfo;
                               6157                 :                :     int         i_tableoid;
                               6158                 :                :     int         i_oid;
                               6159                 :                :     int         i_amname;
                               6160                 :                :     int         i_amhandler;
                               6161                 :                :     int         i_amtype;
                               6162                 :                : 
                               6163                 :                :     /* Before 9.6, there are no user-defined access methods */
                               6164         [ -  + ]:            155 :     if (fout->remoteVersion < 90600)
                               6165                 :                :     {
 2944 alvherre@alvh.no-ip.     6166                 :UBC           0 :         *numAccessMethods = 0;
                               6167                 :              0 :         return NULL;
                               6168                 :                :     }
                               6169                 :                : 
 2944 alvherre@alvh.no-ip.     6170                 :CBC         155 :     query = createPQExpBuffer();
                               6171                 :                : 
                               6172                 :                :     /* Select all access methods from pg_am table */
 1746 drowley@postgresql.o     6173                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, "
                               6174                 :                :                          "amhandler::pg_catalog.regproc AS amhandler "
                               6175                 :                :                          "FROM pg_am");
                               6176                 :                : 
 2944 alvherre@alvh.no-ip.     6177                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6178                 :                : 
                               6179                 :            155 :     ntups = PQntuples(res);
                               6180                 :            155 :     *numAccessMethods = ntups;
                               6181                 :                : 
                               6182                 :            155 :     aminfo = (AccessMethodInfo *) pg_malloc(ntups * sizeof(AccessMethodInfo));
                               6183                 :                : 
                               6184                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               6185                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6186                 :            155 :     i_amname = PQfnumber(res, "amname");
                               6187                 :            155 :     i_amhandler = PQfnumber(res, "amhandler");
                               6188                 :            155 :     i_amtype = PQfnumber(res, "amtype");
                               6189                 :                : 
                               6190         [ +  + ]:           1362 :     for (i = 0; i < ntups; i++)
                               6191                 :                :     {
                               6192                 :           1207 :         aminfo[i].dobj.objType = DO_ACCESS_METHOD;
                               6193                 :           1207 :         aminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6194                 :           1207 :         aminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6195                 :           1207 :         AssignDumpId(&aminfo[i].dobj);
                               6196                 :           1207 :         aminfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_amname));
                               6197                 :           1207 :         aminfo[i].dobj.namespace = NULL;
                               6198                 :           1207 :         aminfo[i].amhandler = pg_strdup(PQgetvalue(res, i, i_amhandler));
                               6199                 :           1207 :         aminfo[i].amtype = *(PQgetvalue(res, i, i_amtype));
                               6200                 :                : 
                               6201                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6202                 :           1207 :         selectDumpableAccessMethod(&(aminfo[i]), fout);
                               6203                 :                :     }
                               6204                 :                : 
 2944 alvherre@alvh.no-ip.     6205                 :            155 :     PQclear(res);
                               6206                 :                : 
                               6207                 :            155 :     destroyPQExpBuffer(query);
                               6208                 :                : 
                               6209                 :            155 :     return aminfo;
                               6210                 :                : }
                               6211                 :                : 
                               6212                 :                : 
                               6213                 :                : /*
                               6214                 :                :  * getOpclasses:
                               6215                 :                :  *    read all opclasses in the system catalogs and return them in the
                               6216                 :                :  * OpclassInfo* structure
                               6217                 :                :  *
                               6218                 :                :  *  numOpclasses is set to the number of opclasses read in
                               6219                 :                :  */
                               6220                 :                : OpclassInfo *
 4451 rhaas@postgresql.org     6221                 :            155 : getOpclasses(Archive *fout, int *numOpclasses)
                               6222                 :                : {
                               6223                 :                :     PGresult   *res;
                               6224                 :                :     int         ntups;
                               6225                 :                :     int         i;
 7929 tgl@sss.pgh.pa.us        6226                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               6227                 :                :     OpclassInfo *opcinfo;
                               6228                 :                :     int         i_tableoid;
                               6229                 :                :     int         i_oid;
                               6230                 :                :     int         i_opcname;
                               6231                 :                :     int         i_opcnamespace;
                               6232                 :                :     int         i_opcowner;
                               6233                 :                : 
                               6234                 :                :     /*
                               6235                 :                :      * find all opclasses, including builtin opclasses; we filter out
                               6236                 :                :      * system-defined opclasses at dump-out time.
                               6237                 :                :      */
                               6238                 :                : 
  586 drowley@postgresql.o     6239                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
                               6240                 :                :                          "opcnamespace, "
                               6241                 :                :                          "opcowner "
                               6242                 :                :                          "FROM pg_opclass");
                               6243                 :                : 
 4450 rhaas@postgresql.org     6244                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6245                 :                : 
 7929 tgl@sss.pgh.pa.us        6246                 :            155 :     ntups = PQntuples(res);
                               6247                 :            155 :     *numOpclasses = ntups;
                               6248                 :                : 
 4524 bruce@momjian.us         6249                 :            155 :     opcinfo = (OpclassInfo *) pg_malloc(ntups * sizeof(OpclassInfo));
                               6250                 :                : 
 7435 tgl@sss.pgh.pa.us        6251                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 7929                          6252                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6253                 :            155 :     i_opcname = PQfnumber(res, "opcname");
                               6254                 :            155 :     i_opcnamespace = PQfnumber(res, "opcnamespace");
  835                          6255                 :            155 :     i_opcowner = PQfnumber(res, "opcowner");
                               6256                 :                : 
 7929                          6257         [ +  + ]:          27743 :     for (i = 0; i < ntups; i++)
                               6258                 :                :     {
 7435                          6259                 :          27588 :         opcinfo[i].dobj.objType = DO_OPCLASS;
                               6260                 :          27588 :         opcinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6261                 :          27588 :         opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6262                 :          27588 :         AssignDumpId(&opcinfo[i].dobj);
 4524 bruce@momjian.us         6263                 :          27588 :         opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
 4451 rhaas@postgresql.org     6264                 :          55176 :         opcinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6265                 :          27588 :             findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)));
  835 tgl@sss.pgh.pa.us        6266                 :          27588 :         opcinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opcowner));
                               6267                 :                : 
                               6268                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6269                 :          27588 :         selectDumpableObject(&(opcinfo[i].dobj), fout);
                               6270                 :                :     }
                               6271                 :                : 
 7929 tgl@sss.pgh.pa.us        6272                 :            155 :     PQclear(res);
                               6273                 :                : 
                               6274                 :            155 :     destroyPQExpBuffer(query);
                               6275                 :                : 
                               6276                 :            155 :     return opcinfo;
                               6277                 :                : }
                               6278                 :                : 
                               6279                 :                : /*
                               6280                 :                :  * getOpfamilies:
                               6281                 :                :  *    read all opfamilies in the system catalogs and return them in the
                               6282                 :                :  * OpfamilyInfo* structure
                               6283                 :                :  *
                               6284                 :                :  *  numOpfamilies is set to the number of opfamilies read in
                               6285                 :                :  */
                               6286                 :                : OpfamilyInfo *
 4451 rhaas@postgresql.org     6287                 :            155 : getOpfamilies(Archive *fout, int *numOpfamilies)
                               6288                 :                : {
                               6289                 :                :     PGresult   *res;
                               6290                 :                :     int         ntups;
                               6291                 :                :     int         i;
                               6292                 :                :     PQExpBuffer query;
                               6293                 :                :     OpfamilyInfo *opfinfo;
                               6294                 :                :     int         i_tableoid;
                               6295                 :                :     int         i_oid;
                               6296                 :                :     int         i_opfname;
                               6297                 :                :     int         i_opfnamespace;
                               6298                 :                :     int         i_opfowner;
                               6299                 :                : 
 6291 tgl@sss.pgh.pa.us        6300                 :            155 :     query = createPQExpBuffer();
                               6301                 :                : 
                               6302                 :                :     /*
                               6303                 :                :      * find all opfamilies, including builtin opfamilies; we filter out
                               6304                 :                :      * system-defined opfamilies at dump-out time.
                               6305                 :                :      */
                               6306                 :                : 
  586 drowley@postgresql.o     6307                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, opfname, "
                               6308                 :                :                          "opfnamespace, "
                               6309                 :                :                          "opfowner "
                               6310                 :                :                          "FROM pg_opfamily");
                               6311                 :                : 
 4450 rhaas@postgresql.org     6312                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6313                 :                : 
 6291 tgl@sss.pgh.pa.us        6314                 :            155 :     ntups = PQntuples(res);
                               6315                 :            155 :     *numOpfamilies = ntups;
                               6316                 :                : 
 4524 bruce@momjian.us         6317                 :            155 :     opfinfo = (OpfamilyInfo *) pg_malloc(ntups * sizeof(OpfamilyInfo));
                               6318                 :                : 
 6291 tgl@sss.pgh.pa.us        6319                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               6320                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6321                 :            155 :     i_opfname = PQfnumber(res, "opfname");
                               6322                 :            155 :     i_opfnamespace = PQfnumber(res, "opfnamespace");
  835                          6323                 :            155 :     i_opfowner = PQfnumber(res, "opfowner");
                               6324                 :                : 
 6291                          6325         [ +  + ]:          22912 :     for (i = 0; i < ntups; i++)
                               6326                 :                :     {
                               6327                 :          22757 :         opfinfo[i].dobj.objType = DO_OPFAMILY;
                               6328                 :          22757 :         opfinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6329                 :          22757 :         opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6330                 :          22757 :         AssignDumpId(&opfinfo[i].dobj);
 4524 bruce@momjian.us         6331                 :          22757 :         opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
 4451 rhaas@postgresql.org     6332                 :          45514 :         opfinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6333                 :          22757 :             findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)));
  835 tgl@sss.pgh.pa.us        6334                 :          22757 :         opfinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_opfowner));
                               6335                 :                : 
                               6336                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6337                 :          22757 :         selectDumpableObject(&(opfinfo[i].dobj), fout);
                               6338                 :                :     }
                               6339                 :                : 
 6291 tgl@sss.pgh.pa.us        6340                 :            155 :     PQclear(res);
                               6341                 :                : 
                               6342                 :            155 :     destroyPQExpBuffer(query);
                               6343                 :                : 
                               6344                 :            155 :     return opfinfo;
                               6345                 :                : }
                               6346                 :                : 
                               6347                 :                : /*
                               6348                 :                :  * getAggregates:
                               6349                 :                :  *    read all the user-defined aggregates in the system catalogs and
                               6350                 :                :  * return them in the AggInfo* structure
                               6351                 :                :  *
                               6352                 :                :  * numAggs is set to the number of aggregates read in
                               6353                 :                :  */
                               6354                 :                : AggInfo *
 3014                          6355                 :            155 : getAggregates(Archive *fout, int *numAggs)
                               6356                 :                : {
                               6357                 :            155 :     DumpOptions *dopt = fout->dopt;
                               6358                 :                :     PGresult   *res;
                               6359                 :                :     int         ntups;
                               6360                 :                :     int         i;
 8768 bruce@momjian.us         6361                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               6362                 :                :     AggInfo    *agginfo;
                               6363                 :                :     int         i_tableoid;
                               6364                 :                :     int         i_oid;
                               6365                 :                :     int         i_aggname;
                               6366                 :                :     int         i_aggnamespace;
                               6367                 :                :     int         i_pronargs;
                               6368                 :                :     int         i_proargtypes;
                               6369                 :                :     int         i_proowner;
                               6370                 :                :     int         i_aggacl;
                               6371                 :                :     int         i_acldefault;
                               6372                 :                : 
                               6373                 :                :     /*
                               6374                 :                :      * Find all interesting aggregates.  See comment in getFuncs() for the
                               6375                 :                :      * rationale behind the filtering logic.
                               6376                 :                :      */
 2930 sfrost@snowman.net       6377         [ +  - ]:            155 :     if (fout->remoteVersion >= 90600)
                               6378                 :                :     {
                               6379                 :                :         const char *agg_check;
                               6380                 :                : 
 2235 peter_e@gmx.net          6381                 :            310 :         agg_check = (fout->remoteVersion >= 110000 ? "p.prokind = 'a'"
                               6382         [ +  - ]:            155 :                      : "p.proisagg");
                               6383                 :                : 
 2930 sfrost@snowman.net       6384                 :            155 :         appendPQExpBuffer(query, "SELECT p.tableoid, p.oid, "
                               6385                 :                :                           "p.proname AS aggname, "
                               6386                 :                :                           "p.pronamespace AS aggnamespace, "
                               6387                 :                :                           "p.pronargs, p.proargtypes, "
                               6388                 :                :                           "p.proowner, "
                               6389                 :                :                           "p.proacl AS aggacl, "
                               6390                 :                :                           "acldefault('f', p.proowner) AS acldefault "
                               6391                 :                :                           "FROM pg_proc p "
                               6392                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6393                 :                :                           "(p.oid = pip.objoid "
                               6394                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6395                 :                :                           "AND pip.objsubid = 0) "
                               6396                 :                :                           "WHERE %s AND ("
                               6397                 :                :                           "p.pronamespace != "
                               6398                 :                :                           "(SELECT oid FROM pg_namespace "
                               6399                 :                :                           "WHERE nspname = 'pg_catalog') OR "
                               6400                 :                :                           "p.proacl IS DISTINCT FROM pip.initprivs",
                               6401                 :                :                           agg_check);
                               6402         [ +  + ]:            155 :         if (dopt->binary_upgrade)
                               6403                 :             14 :             appendPQExpBufferStr(query,
                               6404                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6405                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6406                 :                :                                  "objid = p.oid AND "
                               6407                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6408                 :                :                                  "deptype = 'e')");
                               6409                 :            155 :         appendPQExpBufferChar(query, ')');
                               6410                 :                :     }
                               6411                 :                :     else
                               6412                 :                :     {
  586 drowley@postgresql.o     6413                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, proname AS aggname, "
                               6414                 :                :                              "pronamespace AS aggnamespace, "
                               6415                 :                :                              "pronargs, proargtypes, "
                               6416                 :                :                              "proowner, "
                               6417                 :                :                              "proacl AS aggacl, "
                               6418                 :                :                              "acldefault('f', proowner) AS acldefault "
                               6419                 :                :                              "FROM pg_proc p "
                               6420                 :                :                              "WHERE proisagg AND ("
                               6421                 :                :                              "pronamespace != "
                               6422                 :                :                              "(SELECT oid FROM pg_namespace "
                               6423                 :                :                              "WHERE nspname = 'pg_catalog')");
  860 tgl@sss.pgh.pa.us        6424         [ #  # ]:              0 :         if (dopt->binary_upgrade)
                               6425                 :              0 :             appendPQExpBufferStr(query,
                               6426                 :                :                                  " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6427                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6428                 :                :                                  "objid = p.oid AND "
                               6429                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6430                 :                :                                  "deptype = 'e')");
                               6431                 :              0 :         appendPQExpBufferChar(query, ')');
                               6432                 :                :     }
                               6433                 :                : 
 4450 rhaas@postgresql.org     6434                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6435                 :                : 
 9716 bruce@momjian.us         6436                 :            155 :     ntups = PQntuples(res);
 8010 tgl@sss.pgh.pa.us        6437                 :            155 :     *numAggs = ntups;
                               6438                 :                : 
 4524 bruce@momjian.us         6439                 :            155 :     agginfo = (AggInfo *) pg_malloc(ntups * sizeof(AggInfo));
                               6440                 :                : 
 7435 tgl@sss.pgh.pa.us        6441                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 8010                          6442                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6443                 :            155 :     i_aggname = PQfnumber(res, "aggname");
                               6444                 :            155 :     i_aggnamespace = PQfnumber(res, "aggnamespace");
 6471                          6445                 :            155 :     i_pronargs = PQfnumber(res, "pronargs");
                               6446                 :            155 :     i_proargtypes = PQfnumber(res, "proargtypes");
  835                          6447                 :            155 :     i_proowner = PQfnumber(res, "proowner");
 8001 peter_e@gmx.net          6448                 :            155 :     i_aggacl = PQfnumber(res, "aggacl");
  860 tgl@sss.pgh.pa.us        6449                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
                               6450                 :                : 
 9716 bruce@momjian.us         6451         [ +  + ]:            461 :     for (i = 0; i < ntups; i++)
                               6452                 :                :     {
 7435 tgl@sss.pgh.pa.us        6453                 :            306 :         agginfo[i].aggfn.dobj.objType = DO_AGG;
                               6454                 :            306 :         agginfo[i].aggfn.dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6455                 :            306 :         agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6456                 :            306 :         AssignDumpId(&agginfo[i].aggfn.dobj);
 4524 bruce@momjian.us         6457                 :            306 :         agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
 4451 rhaas@postgresql.org     6458                 :            612 :         agginfo[i].aggfn.dobj.namespace =
 1328 peter@eisentraut.org     6459                 :            306 :             findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)));
  860 tgl@sss.pgh.pa.us        6460                 :            306 :         agginfo[i].aggfn.dacl.acl = pg_strdup(PQgetvalue(res, i, i_aggacl));
                               6461                 :            306 :         agginfo[i].aggfn.dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6462                 :            306 :         agginfo[i].aggfn.dacl.privtype = 0;
                               6463                 :            306 :         agginfo[i].aggfn.dacl.initprivs = NULL;
  835                          6464                 :            306 :         agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 2489                          6465                 :            306 :         agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */
                               6466                 :            306 :         agginfo[i].aggfn.prorettype = InvalidOid;   /* not saved */
 6471                          6467                 :            306 :         agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               6468         [ +  + ]:            306 :         if (agginfo[i].aggfn.nargs == 0)
                               6469                 :             40 :             agginfo[i].aggfn.argtypes = NULL;
                               6470                 :                :         else
                               6471                 :                :         {
 4524 bruce@momjian.us         6472                 :            266 :             agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
 2741 tgl@sss.pgh.pa.us        6473                 :            266 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               6474                 :            266 :                           agginfo[i].aggfn.argtypes,
                               6475                 :            266 :                           agginfo[i].aggfn.nargs);
                               6476                 :                :         }
  315                          6477                 :            306 :         agginfo[i].aggfn.postponed_def = false; /* might get set during sort */
                               6478                 :                : 
                               6479                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6480                 :            306 :         selectDumpableObject(&(agginfo[i].aggfn.dobj), fout);
                               6481                 :                : 
                               6482                 :                :         /* Mark whether aggregate has an ACL */
  860 tgl@sss.pgh.pa.us        6483         [ +  + ]:            306 :         if (!PQgetisnull(res, i, i_aggacl))
                               6484                 :             25 :             agginfo[i].aggfn.dobj.components |= DUMP_COMPONENT_ACL;
                               6485                 :                :     }
                               6486                 :                : 
 8010                          6487                 :            155 :     PQclear(res);
                               6488                 :                : 
                               6489                 :            155 :     destroyPQExpBuffer(query);
                               6490                 :                : 
                               6491                 :            155 :     return agginfo;
                               6492                 :                : }
                               6493                 :                : 
                               6494                 :                : /*
                               6495                 :                :  * getFuncs:
                               6496                 :                :  *    read all the user-defined functions in the system catalogs and
                               6497                 :                :  * return them in the FuncInfo* structure
                               6498                 :                :  *
                               6499                 :                :  * numFuncs is set to the number of functions read in
                               6500                 :                :  */
                               6501                 :                : FuncInfo *
 3014                          6502                 :            155 : getFuncs(Archive *fout, int *numFuncs)
                               6503                 :                : {
                               6504                 :            155 :     DumpOptions *dopt = fout->dopt;
                               6505                 :                :     PGresult   *res;
                               6506                 :                :     int         ntups;
                               6507                 :                :     int         i;
 8010                          6508                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               6509                 :                :     FuncInfo   *finfo;
                               6510                 :                :     int         i_tableoid;
                               6511                 :                :     int         i_oid;
                               6512                 :                :     int         i_proname;
                               6513                 :                :     int         i_pronamespace;
                               6514                 :                :     int         i_proowner;
                               6515                 :                :     int         i_prolang;
                               6516                 :                :     int         i_pronargs;
                               6517                 :                :     int         i_proargtypes;
                               6518                 :                :     int         i_prorettype;
                               6519                 :                :     int         i_proacl;
                               6520                 :                :     int         i_acldefault;
                               6521                 :                : 
                               6522                 :                :     /*
                               6523                 :                :      * Find all interesting functions.  This is a bit complicated:
                               6524                 :                :      *
                               6525                 :                :      * 1. Always exclude aggregates; those are handled elsewhere.
                               6526                 :                :      *
                               6527                 :                :      * 2. Always exclude functions that are internally dependent on something
                               6528                 :                :      * else, since presumably those will be created as a result of creating
                               6529                 :                :      * the something else.  This currently acts only to suppress constructor
                               6530                 :                :      * functions for range types.  Note this is OK only because the
                               6531                 :                :      * constructors don't have any dependencies the range type doesn't have;
                               6532                 :                :      * otherwise we might not get creation ordering correct.
                               6533                 :                :      *
                               6534                 :                :      * 3. Otherwise, we normally exclude functions in pg_catalog.  However, if
                               6535                 :                :      * they're members of extensions and we are in binary-upgrade mode then
                               6536                 :                :      * include them, since we want to dump extension members individually in
                               6537                 :                :      * that mode.  Also, if they are used by casts or transforms then we need
                               6538                 :                :      * to gather the information about them, though they won't be dumped if
                               6539                 :                :      * they are built-in.  Also, in 9.6 and up, include functions in
                               6540                 :                :      * pg_catalog if they have an ACL different from what's shown in
                               6541                 :                :      * pg_init_privs (so we have to join to pg_init_privs; annoying).
                               6542                 :                :      */
 2930 sfrost@snowman.net       6543         [ +  - ]:            155 :     if (fout->remoteVersion >= 90600)
                               6544                 :                :     {
                               6545                 :                :         const char *not_agg_check;
                               6546                 :                : 
 2235 peter_e@gmx.net          6547                 :            310 :         not_agg_check = (fout->remoteVersion >= 110000 ? "p.prokind <> 'a'"
                               6548         [ +  - ]:            155 :                          : "NOT p.proisagg");
                               6549                 :                : 
 2930 sfrost@snowman.net       6550                 :            155 :         appendPQExpBuffer(query,
                               6551                 :                :                           "SELECT p.tableoid, p.oid, p.proname, p.prolang, "
                               6552                 :                :                           "p.pronargs, p.proargtypes, p.prorettype, "
                               6553                 :                :                           "p.proacl, "
                               6554                 :                :                           "acldefault('f', p.proowner) AS acldefault, "
                               6555                 :                :                           "p.pronamespace, "
                               6556                 :                :                           "p.proowner "
                               6557                 :                :                           "FROM pg_proc p "
                               6558                 :                :                           "LEFT JOIN pg_init_privs pip ON "
                               6559                 :                :                           "(p.oid = pip.objoid "
                               6560                 :                :                           "AND pip.classoid = 'pg_proc'::regclass "
                               6561                 :                :                           "AND pip.objsubid = 0) "
                               6562                 :                :                           "WHERE %s"
                               6563                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6564                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               6565                 :                :                           "objid = p.oid AND deptype = 'i')"
                               6566                 :                :                           "\n  AND ("
                               6567                 :                :                           "\n  pronamespace != "
                               6568                 :                :                           "(SELECT oid FROM pg_namespace "
                               6569                 :                :                           "WHERE nspname = 'pg_catalog')"
                               6570                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               6571                 :                :                           "\n  WHERE pg_cast.oid > %u "
                               6572                 :                :                           "\n  AND p.oid = pg_cast.castfunc)"
                               6573                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               6574                 :                :                           "\n  WHERE pg_transform.oid > %u AND "
                               6575                 :                :                           "\n  (p.oid = pg_transform.trffromsql"
                               6576                 :                :                           "\n  OR p.oid = pg_transform.trftosql))",
                               6577                 :                :                           not_agg_check,
                               6578                 :                :                           g_last_builtin_oid,
                               6579                 :                :                           g_last_builtin_oid);
                               6580         [ +  + ]:            155 :         if (dopt->binary_upgrade)
                               6581                 :             14 :             appendPQExpBufferStr(query,
                               6582                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6583                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6584                 :                :                                  "objid = p.oid AND "
                               6585                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6586                 :                :                                  "deptype = 'e')");
 2760 tgl@sss.pgh.pa.us        6587                 :            155 :         appendPQExpBufferStr(query,
                               6588                 :                :                              "\n  OR p.proacl IS DISTINCT FROM pip.initprivs");
 2930 sfrost@snowman.net       6589                 :            155 :         appendPQExpBufferChar(query, ')');
                               6590                 :                :     }
                               6591                 :                :     else
                               6592                 :                :     {
 8010 tgl@sss.pgh.pa.us        6593                 :UBC           0 :         appendPQExpBuffer(query,
                               6594                 :                :                           "SELECT tableoid, oid, proname, prolang, "
                               6595                 :                :                           "pronargs, proargtypes, prorettype, proacl, "
                               6596                 :                :                           "acldefault('f', proowner) AS acldefault, "
                               6597                 :                :                           "pronamespace, "
                               6598                 :                :                           "proowner "
                               6599                 :                :                           "FROM pg_proc p "
                               6600                 :                :                           "WHERE NOT proisagg"
                               6601                 :                :                           "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
                               6602                 :                :                           "WHERE classid = 'pg_proc'::regclass AND "
                               6603                 :                :                           "objid = p.oid AND deptype = 'i')"
                               6604                 :                :                           "\n  AND ("
                               6605                 :                :                           "\n  pronamespace != "
                               6606                 :                :                           "(SELECT oid FROM pg_namespace "
                               6607                 :                :                           "WHERE nspname = 'pg_catalog')"
                               6608                 :                :                           "\n  OR EXISTS (SELECT 1 FROM pg_cast"
                               6609                 :                :                           "\n  WHERE pg_cast.oid > '%u'::oid"
                               6610                 :                :                           "\n  AND p.oid = pg_cast.castfunc)",
                               6611                 :                :                           g_last_builtin_oid);
                               6612                 :                : 
 2671 sfrost@snowman.net       6613         [ #  # ]:              0 :         if (fout->remoteVersion >= 90500)
                               6614                 :              0 :             appendPQExpBuffer(query,
                               6615                 :                :                               "\n  OR EXISTS (SELECT 1 FROM pg_transform"
                               6616                 :                :                               "\n  WHERE pg_transform.oid > '%u'::oid"
                               6617                 :                :                               "\n  AND (p.oid = pg_transform.trffromsql"
                               6618                 :                :                               "\n  OR p.oid = pg_transform.trftosql))",
                               6619                 :                :                               g_last_builtin_oid);
                               6620                 :                : 
  852 tgl@sss.pgh.pa.us        6621         [ #  # ]:              0 :         if (dopt->binary_upgrade)
 3800 heikki.linnakangas@i     6622                 :              0 :             appendPQExpBufferStr(query,
                               6623                 :                :                                  "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
                               6624                 :                :                                  "classid = 'pg_proc'::regclass AND "
                               6625                 :                :                                  "objid = p.oid AND "
                               6626                 :                :                                  "refclassid = 'pg_extension'::regclass AND "
                               6627                 :                :                                  "deptype = 'e')");
                               6628                 :              0 :         appendPQExpBufferChar(query, ')');
                               6629                 :                :     }
                               6630                 :                : 
 4450 rhaas@postgresql.org     6631                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6632                 :                : 
 8010 tgl@sss.pgh.pa.us        6633                 :            155 :     ntups = PQntuples(res);
                               6634                 :                : 
                               6635                 :            155 :     *numFuncs = ntups;
                               6636                 :                : 
 4212                          6637                 :            155 :     finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
                               6638                 :                : 
 7435                          6639                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 8010                          6640                 :            155 :     i_oid = PQfnumber(res, "oid");
                               6641                 :            155 :     i_proname = PQfnumber(res, "proname");
                               6642                 :            155 :     i_pronamespace = PQfnumber(res, "pronamespace");
  835                          6643                 :            155 :     i_proowner = PQfnumber(res, "proowner");
 8010                          6644                 :            155 :     i_prolang = PQfnumber(res, "prolang");
                               6645                 :            155 :     i_pronargs = PQfnumber(res, "pronargs");
                               6646                 :            155 :     i_proargtypes = PQfnumber(res, "proargtypes");
                               6647                 :            155 :     i_prorettype = PQfnumber(res, "prorettype");
 8001 peter_e@gmx.net          6648                 :            155 :     i_proacl = PQfnumber(res, "proacl");
  860 tgl@sss.pgh.pa.us        6649                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
                               6650                 :                : 
 8010                          6651         [ +  + ]:           3918 :     for (i = 0; i < ntups; i++)
                               6652                 :                :     {
 7435                          6653                 :           3763 :         finfo[i].dobj.objType = DO_FUNC;
                               6654                 :           3763 :         finfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               6655                 :           3763 :         finfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               6656                 :           3763 :         AssignDumpId(&finfo[i].dobj);
 4524 bruce@momjian.us         6657                 :           3763 :         finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
 6756                          6658                 :           7526 :         finfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6659                 :           3763 :             findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)));
  860 tgl@sss.pgh.pa.us        6660                 :           3763 :         finfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_proacl));
                               6661                 :           3763 :         finfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6662                 :           3763 :         finfo[i].dacl.privtype = 0;
                               6663                 :           3763 :         finfo[i].dacl.initprivs = NULL;
  835                          6664                 :           3763 :         finfo[i].rolname = getRoleName(PQgetvalue(res, i, i_proowner));
 8010                          6665                 :           3763 :         finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
 7435                          6666                 :           3763 :         finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
 8010                          6667                 :           3763 :         finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
                               6668         [ +  + ]:           3763 :         if (finfo[i].nargs == 0)
                               6669                 :            827 :             finfo[i].argtypes = NULL;
                               6670                 :                :         else
                               6671                 :                :         {
 4524 bruce@momjian.us         6672                 :           2936 :             finfo[i].argtypes = (Oid *) pg_malloc(finfo[i].nargs * sizeof(Oid));
 7435 tgl@sss.pgh.pa.us        6673                 :           2936 :             parseOidArray(PQgetvalue(res, i, i_proargtypes),
                               6674                 :           2936 :                           finfo[i].argtypes, finfo[i].nargs);
                               6675                 :                :         }
  315                          6676                 :           3763 :         finfo[i].postponed_def = false; /* might get set during sort */
                               6677                 :                : 
                               6678                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       6679                 :           3763 :         selectDumpableObject(&(finfo[i].dobj), fout);
                               6680                 :                : 
                               6681                 :                :         /* Mark whether function has an ACL */
  860 tgl@sss.pgh.pa.us        6682         [ +  + ]:           3763 :         if (!PQgetisnull(res, i, i_proacl))
                               6683                 :            142 :             finfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               6684                 :                :     }
                               6685                 :                : 
 8010                          6686                 :            155 :     PQclear(res);
                               6687                 :                : 
                               6688                 :            155 :     destroyPQExpBuffer(query);
                               6689                 :                : 
                               6690                 :            155 :     return finfo;
                               6691                 :                : }
                               6692                 :                : 
                               6693                 :                : /*
                               6694                 :                :  * getTables
                               6695                 :                :  *    read all the tables (no indexes) in the system catalogs,
                               6696                 :                :  *    and return them as an array of TableInfo structures
                               6697                 :                :  *
                               6698                 :                :  * *numTables is set to the number of tables read in
                               6699                 :                :  */
                               6700                 :                : TableInfo *
 3014                          6701                 :            156 : getTables(Archive *fout, int *numTables)
                               6702                 :                : {
                               6703                 :            156 :     DumpOptions *dopt = fout->dopt;
                               6704                 :                :     PGresult   *res;
                               6705                 :                :     int         ntups;
                               6706                 :                :     int         i;
 8010                          6707                 :            156 :     PQExpBuffer query = createPQExpBuffer();
                               6708                 :                :     TableInfo  *tblinfo;
                               6709                 :                :     int         i_reltableoid;
                               6710                 :                :     int         i_reloid;
                               6711                 :                :     int         i_relname;
                               6712                 :                :     int         i_relnamespace;
                               6713                 :                :     int         i_relkind;
                               6714                 :                :     int         i_reltype;
                               6715                 :                :     int         i_relowner;
                               6716                 :                :     int         i_relchecks;
                               6717                 :                :     int         i_relhasindex;
                               6718                 :                :     int         i_relhasrules;
                               6719                 :                :     int         i_relpages;
                               6720                 :                :     int         i_toastpages;
                               6721                 :                :     int         i_owning_tab;
                               6722                 :                :     int         i_owning_col;
                               6723                 :                :     int         i_reltablespace;
                               6724                 :                :     int         i_relhasoids;
                               6725                 :                :     int         i_relhastriggers;
                               6726                 :                :     int         i_relpersistence;
                               6727                 :                :     int         i_relispopulated;
                               6728                 :                :     int         i_relreplident;
                               6729                 :                :     int         i_relrowsec;
                               6730                 :                :     int         i_relforcerowsec;
                               6731                 :                :     int         i_relfrozenxid;
                               6732                 :                :     int         i_toastfrozenxid;
                               6733                 :                :     int         i_toastoid;
                               6734                 :                :     int         i_relminmxid;
                               6735                 :                :     int         i_toastminmxid;
                               6736                 :                :     int         i_reloptions;
                               6737                 :                :     int         i_checkoption;
                               6738                 :                :     int         i_toastreloptions;
                               6739                 :                :     int         i_reloftype;
                               6740                 :                :     int         i_foreignserver;
                               6741                 :                :     int         i_amname;
                               6742                 :                :     int         i_is_identity_sequence;
                               6743                 :                :     int         i_relacl;
                               6744                 :                :     int         i_acldefault;
                               6745                 :                :     int         i_ispartition;
                               6746                 :                : 
                               6747                 :                :     /*
                               6748                 :                :      * Find all the tables and table-like objects.
                               6749                 :                :      *
                               6750                 :                :      * We must fetch all tables in this phase because otherwise we cannot
                               6751                 :                :      * correctly identify inherited columns, owned sequences, etc.
                               6752                 :                :      *
                               6753                 :                :      * We include system catalogs, so that we can work if a user table is
                               6754                 :                :      * defined to inherit from a system catalog (pretty weird, but...)
                               6755                 :                :      *
                               6756                 :                :      * Note: in this phase we should collect only a minimal amount of
                               6757                 :                :      * information about each table, basically just enough to decide if it is
                               6758                 :                :      * interesting.  In particular, since we do not yet have lock on any user
                               6759                 :                :      * table, we MUST NOT invoke any server-side data collection functions
                               6760                 :                :      * (for instance, pg_get_partkeydef()).  Those are likely to fail or give
                               6761                 :                :      * wrong answers if any concurrent DDL is happening.
                               6762                 :                :      */
                               6763                 :                : 
  586 drowley@postgresql.o     6764                 :            156 :     appendPQExpBufferStr(query,
                               6765                 :                :                          "SELECT c.tableoid, c.oid, c.relname, "
                               6766                 :                :                          "c.relnamespace, c.relkind, c.reltype, "
                               6767                 :                :                          "c.relowner, "
                               6768                 :                :                          "c.relchecks, "
                               6769                 :                :                          "c.relhasindex, c.relhasrules, c.relpages, "
                               6770                 :                :                          "c.relhastriggers, "
                               6771                 :                :                          "c.relpersistence, "
                               6772                 :                :                          "c.reloftype, "
                               6773                 :                :                          "c.relacl, "
                               6774                 :                :                          "acldefault(CASE WHEN c.relkind = " CppAsString2(RELKIND_SEQUENCE)
                               6775                 :                :                          " THEN 's'::\"char\" ELSE 'r'::\"char\" END, c.relowner) AS acldefault, "
                               6776                 :                :                          "CASE WHEN c.relkind = " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN "
                               6777                 :                :                          "(SELECT ftserver FROM pg_catalog.pg_foreign_table WHERE ftrelid = c.oid) "
                               6778                 :                :                          "ELSE 0 END AS foreignserver, "
                               6779                 :                :                          "c.relfrozenxid, tc.relfrozenxid AS tfrozenxid, "
                               6780                 :                :                          "tc.oid AS toid, "
                               6781                 :                :                          "tc.relpages AS toastpages, "
                               6782                 :                :                          "tc.reloptions AS toast_reloptions, "
                               6783                 :                :                          "d.refobjid AS owning_tab, "
                               6784                 :                :                          "d.refobjsubid AS owning_col, "
                               6785                 :                :                          "tsp.spcname AS reltablespace, ");
                               6786                 :                : 
  908 tgl@sss.pgh.pa.us        6787         [ +  - ]:            156 :     if (fout->remoteVersion >= 120000)
                               6788                 :            156 :         appendPQExpBufferStr(query,
                               6789                 :                :                              "false AS relhasoids, ");
                               6790                 :                :     else
  908 tgl@sss.pgh.pa.us        6791                 :UBC           0 :         appendPQExpBufferStr(query,
                               6792                 :                :                              "c.relhasoids, ");
                               6793                 :                : 
  908 tgl@sss.pgh.pa.us        6794         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90300)
                               6795                 :            156 :         appendPQExpBufferStr(query,
                               6796                 :                :                              "c.relispopulated, ");
                               6797                 :                :     else
  908 tgl@sss.pgh.pa.us        6798                 :UBC           0 :         appendPQExpBufferStr(query,
                               6799                 :                :                              "'t' as relispopulated, ");
                               6800                 :                : 
  908 tgl@sss.pgh.pa.us        6801         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90400)
                               6802                 :            156 :         appendPQExpBufferStr(query,
                               6803                 :                :                              "c.relreplident, ");
                               6804                 :                :     else
  908 tgl@sss.pgh.pa.us        6805                 :UBC           0 :         appendPQExpBufferStr(query,
                               6806                 :                :                              "'d' AS relreplident, ");
                               6807                 :                : 
  908 tgl@sss.pgh.pa.us        6808         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90500)
                               6809                 :            156 :         appendPQExpBufferStr(query,
                               6810                 :                :                              "c.relrowsecurity, c.relforcerowsecurity, ");
                               6811                 :                :     else
  908 tgl@sss.pgh.pa.us        6812                 :UBC           0 :         appendPQExpBufferStr(query,
                               6813                 :                :                              "false AS relrowsecurity, "
                               6814                 :                :                              "false AS relforcerowsecurity, ");
                               6815                 :                : 
  908 tgl@sss.pgh.pa.us        6816         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90300)
                               6817                 :            156 :         appendPQExpBufferStr(query,
                               6818                 :                :                              "c.relminmxid, tc.relminmxid AS tminmxid, ");
                               6819                 :                :     else
  908 tgl@sss.pgh.pa.us        6820                 :UBC           0 :         appendPQExpBufferStr(query,
                               6821                 :                :                              "0 AS relminmxid, 0 AS tminmxid, ");
                               6822                 :                : 
  908 tgl@sss.pgh.pa.us        6823         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90300)
                               6824                 :            156 :         appendPQExpBufferStr(query,
                               6825                 :                :                              "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
                               6826                 :                :                              "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
                               6827                 :                :                              "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, ");
                               6828                 :                :     else
  908 tgl@sss.pgh.pa.us        6829                 :UBC           0 :         appendPQExpBufferStr(query,
                               6830                 :                :                              "c.reloptions, NULL AS checkoption, ");
                               6831                 :                : 
 2930 sfrost@snowman.net       6832         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90600)
  908 tgl@sss.pgh.pa.us        6833                 :            156 :         appendPQExpBufferStr(query,
                               6834                 :                :                              "am.amname, ");
                               6835                 :                :     else
  908 tgl@sss.pgh.pa.us        6836                 :UBC           0 :         appendPQExpBufferStr(query,
                               6837                 :                :                              "NULL AS amname, ");
                               6838                 :                : 
  908 tgl@sss.pgh.pa.us        6839         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 90600)
                               6840                 :            156 :         appendPQExpBufferStr(query,
                               6841                 :                :                              "(d.deptype = 'i') IS TRUE AS is_identity_sequence, ");
                               6842                 :                :     else
  908 tgl@sss.pgh.pa.us        6843                 :UBC           0 :         appendPQExpBufferStr(query,
                               6844                 :                :                              "false AS is_identity_sequence, ");
                               6845                 :                : 
  908 tgl@sss.pgh.pa.us        6846         [ +  - ]:CBC         156 :     if (fout->remoteVersion >= 100000)
                               6847                 :            156 :         appendPQExpBufferStr(query,
                               6848                 :                :                              "c.relispartition AS ispartition ");
                               6849                 :                :     else
  908 tgl@sss.pgh.pa.us        6850                 :UBC           0 :         appendPQExpBufferStr(query,
                               6851                 :                :                              "false AS ispartition ");
                               6852                 :                : 
                               6853                 :                :     /*
                               6854                 :                :      * Left join to pg_depend to pick up dependency info linking sequences to
                               6855                 :                :      * their owning column, if any (note this dependency is AUTO except for
                               6856                 :                :      * identity sequences, where it's INTERNAL). Also join to pg_tablespace to
                               6857                 :                :      * collect the spcname.
                               6858                 :                :      */
  908 tgl@sss.pgh.pa.us        6859                 :CBC         156 :     appendPQExpBufferStr(query,
                               6860                 :                :                          "\nFROM pg_class c\n"
                               6861                 :                :                          "LEFT JOIN pg_depend d ON "
                               6862                 :                :                          "(c.relkind = " CppAsString2(RELKIND_SEQUENCE) " AND "
                               6863                 :                :                          "d.classid = 'pg_class'::regclass AND d.objid = c.oid AND "
                               6864                 :                :                          "d.objsubid = 0 AND "
                               6865                 :                :                          "d.refclassid = 'pg_class'::regclass AND d.deptype IN ('a', 'i'))\n"
                               6866                 :                :                          "LEFT JOIN pg_tablespace tsp ON (tsp.oid = c.reltablespace)\n");
                               6867                 :                : 
                               6868                 :                :     /*
                               6869                 :                :      * In 9.6 and up, left join to pg_am to pick up the amname.
                               6870                 :                :      */
                               6871         [ +  - ]:            156 :     if (fout->remoteVersion >= 90600)
                               6872                 :            156 :         appendPQExpBufferStr(query,
                               6873                 :                :                              "LEFT JOIN pg_am am ON (c.relam = am.oid)\n");
                               6874                 :                : 
                               6875                 :                :     /*
                               6876                 :                :      * We purposefully ignore toast OIDs for partitioned tables; the reason is
                               6877                 :                :      * that versions 10 and 11 have them, but later versions do not, so
                               6878                 :                :      * emitting them causes the upgrade to fail.
                               6879                 :                :      */
  860                          6880                 :            156 :     appendPQExpBufferStr(query,
                               6881                 :                :                          "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid"
                               6882                 :                :                          " AND tc.relkind = " CppAsString2(RELKIND_TOASTVALUE)
                               6883                 :                :                          " AND c.relkind <> " CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
                               6884                 :                : 
                               6885                 :                :     /*
                               6886                 :                :      * Restrict to interesting relkinds (in particular, not indexes).  Not all
                               6887                 :                :      * relkinds are possible in older servers, but it's not worth the trouble
                               6888                 :                :      * to emit a version-dependent list.
                               6889                 :                :      *
                               6890                 :                :      * Composite-type table entries won't be dumped as such, but we have to
                               6891                 :                :      * make a DumpableObject for them so that we can track dependencies of the
                               6892                 :                :      * composite type (pg_depend entries for columns of the composite type
                               6893                 :                :      * link to the pg_class entry not the pg_type entry).
                               6894                 :                :      */
  908                          6895                 :            156 :     appendPQExpBufferStr(query,
                               6896                 :                :                          "WHERE c.relkind IN ("
                               6897                 :                :                          CppAsString2(RELKIND_RELATION) ", "
                               6898                 :                :                          CppAsString2(RELKIND_SEQUENCE) ", "
                               6899                 :                :                          CppAsString2(RELKIND_VIEW) ", "
                               6900                 :                :                          CppAsString2(RELKIND_COMPOSITE_TYPE) ", "
                               6901                 :                :                          CppAsString2(RELKIND_MATVIEW) ", "
                               6902                 :                :                          CppAsString2(RELKIND_FOREIGN_TABLE) ", "
                               6903                 :                :                          CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n"
                               6904                 :                :                          "ORDER BY c.oid");
                               6905                 :                : 
 4450 rhaas@postgresql.org     6906                 :            156 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               6907                 :                : 
 8010 tgl@sss.pgh.pa.us        6908                 :            156 :     ntups = PQntuples(res);
                               6909                 :                : 
                               6910                 :            156 :     *numTables = ntups;
                               6911                 :                : 
                               6912                 :                :     /*
                               6913                 :                :      * Extract data from result and lock dumpable tables.  We do the locking
                               6914                 :                :      * before anything else, to minimize the window wherein a table could
                               6915                 :                :      * disappear under us.
                               6916                 :                :      *
                               6917                 :                :      * Note that we have to save info about all tables here, even when dumping
                               6918                 :                :      * only one, because we don't yet know which tables might be inheritance
                               6919                 :                :      * ancestors of the target table.
                               6920                 :                :      */
 4212                          6921                 :            156 :     tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
                               6922                 :                : 
 7435                          6923                 :            156 :     i_reltableoid = PQfnumber(res, "tableoid");
 8010                          6924                 :            156 :     i_reloid = PQfnumber(res, "oid");
                               6925                 :            156 :     i_relname = PQfnumber(res, "relname");
                               6926                 :            156 :     i_relnamespace = PQfnumber(res, "relnamespace");
                               6927                 :            156 :     i_relkind = PQfnumber(res, "relkind");
  860                          6928                 :            156 :     i_reltype = PQfnumber(res, "reltype");
  835                          6929                 :            156 :     i_relowner = PQfnumber(res, "relowner");
 8010                          6930                 :            156 :     i_relchecks = PQfnumber(res, "relchecks");
                               6931                 :            156 :     i_relhasindex = PQfnumber(res, "relhasindex");
                               6932                 :            156 :     i_relhasrules = PQfnumber(res, "relhasrules");
  908                          6933                 :            156 :     i_relpages = PQfnumber(res, "relpages");
  860                          6934                 :            156 :     i_toastpages = PQfnumber(res, "toastpages");
  908                          6935                 :            156 :     i_owning_tab = PQfnumber(res, "owning_tab");
                               6936                 :            156 :     i_owning_col = PQfnumber(res, "owning_col");
                               6937                 :            156 :     i_reltablespace = PQfnumber(res, "reltablespace");
                               6938                 :            156 :     i_relhasoids = PQfnumber(res, "relhasoids");
                               6939                 :            156 :     i_relhastriggers = PQfnumber(res, "relhastriggers");
                               6940                 :            156 :     i_relpersistence = PQfnumber(res, "relpersistence");
                               6941                 :            156 :     i_relispopulated = PQfnumber(res, "relispopulated");
                               6942                 :            156 :     i_relreplident = PQfnumber(res, "relreplident");
 3490 sfrost@snowman.net       6943                 :            156 :     i_relrowsec = PQfnumber(res, "relrowsecurity");
 3115                          6944                 :            156 :     i_relforcerowsec = PQfnumber(res, "relforcerowsecurity");
 5534 bruce@momjian.us         6945                 :            156 :     i_relfrozenxid = PQfnumber(res, "relfrozenxid");
 4755                          6946                 :            156 :     i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
  908 tgl@sss.pgh.pa.us        6947                 :            156 :     i_toastoid = PQfnumber(res, "toid");
                               6948                 :            156 :     i_relminmxid = PQfnumber(res, "relminmxid");
 3574 bruce@momjian.us         6949                 :            156 :     i_toastminmxid = PQfnumber(res, "tminmxid");
 6496                          6950                 :            156 :     i_reloptions = PQfnumber(res, "reloptions");
 3923 sfrost@snowman.net       6951                 :            156 :     i_checkoption = PQfnumber(res, "checkoption");
 5550 alvherre@alvh.no-ip.     6952                 :            156 :     i_toastreloptions = PQfnumber(res, "toast_reloptions");
 5190 peter_e@gmx.net          6953                 :            156 :     i_reloftype = PQfnumber(res, "reloftype");
  908 tgl@sss.pgh.pa.us        6954                 :            156 :     i_foreignserver = PQfnumber(res, "foreignserver");
                               6955                 :            156 :     i_amname = PQfnumber(res, "amname");
 2565 peter_e@gmx.net          6956                 :            156 :     i_is_identity_sequence = PQfnumber(res, "is_identity_sequence");
  908 tgl@sss.pgh.pa.us        6957                 :            156 :     i_relacl = PQfnumber(res, "relacl");
  860                          6958                 :            156 :     i_acldefault = PQfnumber(res, "acldefault");
 2537 sfrost@snowman.net       6959                 :            156 :     i_ispartition = PQfnumber(res, "ispartition");
                               6960                 :                : 
 2741 tgl@sss.pgh.pa.us        6961         [ +  + ]:            156 :     if (dopt->lockWaitTimeout)
                               6962                 :                :     {
                               6963                 :                :         /*
                               6964                 :                :          * Arrange to fail instead of waiting forever for a table lock.
                               6965                 :                :          *
                               6966                 :                :          * NB: this coding assumes that the only queries issued within the
                               6967                 :                :          * following loop are LOCK TABLEs; else the timeout may be undesirably
                               6968                 :                :          * applied to other things too.
                               6969                 :                :          */
 5747                          6970                 :              2 :         resetPQExpBuffer(query);
 3800 heikki.linnakangas@i     6971                 :              2 :         appendPQExpBufferStr(query, "SET statement_timeout = ");
 3470 alvherre@alvh.no-ip.     6972                 :              2 :         appendStringLiteralConn(query, dopt->lockWaitTimeout, GetConnection(fout));
 4450 rhaas@postgresql.org     6973                 :              2 :         ExecuteSqlStatement(fout, query->data);
                               6974                 :                :     }
                               6975                 :                : 
  467 tgl@sss.pgh.pa.us        6976                 :            156 :     resetPQExpBuffer(query);
                               6977                 :                : 
 8010                          6978         [ +  + ]:          39679 :     for (i = 0; i < ntups; i++)
                               6979                 :                :     {
 7435                          6980                 :          39523 :         tblinfo[i].dobj.objType = DO_TABLE;
                               6981                 :          39523 :         tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
                               6982                 :          39523 :         tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
                               6983                 :          39523 :         AssignDumpId(&tblinfo[i].dobj);
 4524 bruce@momjian.us         6984                 :          39523 :         tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
 4451 rhaas@postgresql.org     6985                 :          79046 :         tblinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     6986                 :          39523 :             findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)));
  860 tgl@sss.pgh.pa.us        6987                 :          39523 :         tblinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_relacl));
                               6988                 :          39523 :         tblinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               6989                 :          39523 :         tblinfo[i].dacl.privtype = 0;
                               6990                 :          39523 :         tblinfo[i].dacl.initprivs = NULL;
 8010                          6991                 :          39523 :         tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
  860                          6992                 :          39523 :         tblinfo[i].reltype = atooid(PQgetvalue(res, i, i_reltype));
  835                          6993                 :          39523 :         tblinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_relowner));
  908                          6994                 :          39523 :         tblinfo[i].ncheck = atoi(PQgetvalue(res, i, i_relchecks));
 8010                          6995                 :          39523 :         tblinfo[i].hasindex = (strcmp(PQgetvalue(res, i, i_relhasindex), "t") == 0);
                               6996                 :          39523 :         tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
 4039 andrew@dunslane.net      6997                 :          39523 :         tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
  860 tgl@sss.pgh.pa.us        6998         [ +  + ]:          39523 :         if (PQgetisnull(res, i, i_toastpages))
                               6999                 :          31372 :             tblinfo[i].toastpages = 0;
                               7000                 :                :         else
                               7001                 :           8151 :             tblinfo[i].toastpages = atoi(PQgetvalue(res, i, i_toastpages));
 7909                          7002         [ +  + ]:          39523 :         if (PQgetisnull(res, i, i_owning_tab))
                               7003                 :                :         {
 7435                          7004                 :          39192 :             tblinfo[i].owning_tab = InvalidOid;
 7909                          7005                 :          39192 :             tblinfo[i].owning_col = 0;
                               7006                 :                :         }
                               7007                 :                :         else
                               7008                 :                :         {
 7435                          7009                 :            331 :             tblinfo[i].owning_tab = atooid(PQgetvalue(res, i, i_owning_tab));
 7909                          7010                 :            331 :             tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
                               7011                 :                :         }
 4524 bruce@momjian.us         7012                 :          39523 :         tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
  908 tgl@sss.pgh.pa.us        7013                 :          39523 :         tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
                               7014                 :          39523 :         tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
                               7015                 :          39523 :         tblinfo[i].relpersistence = *(PQgetvalue(res, i, i_relpersistence));
                               7016                 :          39523 :         tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
                               7017                 :          39523 :         tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
                               7018                 :          39523 :         tblinfo[i].rowsec = (strcmp(PQgetvalue(res, i, i_relrowsec), "t") == 0);
                               7019                 :          39523 :         tblinfo[i].forcerowsec = (strcmp(PQgetvalue(res, i, i_relforcerowsec), "t") == 0);
                               7020                 :          39523 :         tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
                               7021                 :          39523 :         tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
                               7022                 :          39523 :         tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
                               7023                 :          39523 :         tblinfo[i].minmxid = atooid(PQgetvalue(res, i, i_relminmxid));
                               7024                 :          39523 :         tblinfo[i].toast_minmxid = atooid(PQgetvalue(res, i, i_toastminmxid));
 4524 bruce@momjian.us         7025                 :          39523 :         tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
  908 tgl@sss.pgh.pa.us        7026         [ +  + ]:          39523 :         if (PQgetisnull(res, i, i_checkoption))
 3923 sfrost@snowman.net       7027                 :          39476 :             tblinfo[i].checkoption = NULL;
                               7028                 :                :         else
                               7029                 :             47 :             tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
 4524 bruce@momjian.us         7030                 :          39523 :         tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
  860 tgl@sss.pgh.pa.us        7031                 :          39523 :         tblinfo[i].reloftype = atooid(PQgetvalue(res, i, i_reloftype));
  908                          7032                 :          39523 :         tblinfo[i].foreign_server = atooid(PQgetvalue(res, i, i_foreignserver));
 1866 andres@anarazel.de       7033         [ +  + ]:          39523 :         if (PQgetisnull(res, i, i_amname))
                               7034                 :          23809 :             tblinfo[i].amname = NULL;
                               7035                 :                :         else
                               7036                 :          15714 :             tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname));
  908 tgl@sss.pgh.pa.us        7037                 :          39523 :         tblinfo[i].is_identity_sequence = (strcmp(PQgetvalue(res, i, i_is_identity_sequence), "t") == 0);
                               7038                 :          39523 :         tblinfo[i].ispartition = (strcmp(PQgetvalue(res, i, i_ispartition), "t") == 0);
                               7039                 :                : 
                               7040                 :                :         /* other fields were zeroed above */
                               7041                 :                : 
                               7042                 :                :         /*
                               7043                 :                :          * Decide whether we want to dump this table.
                               7044                 :                :          */
 7033                          7045         [ +  + ]:          39523 :         if (tblinfo[i].relkind == RELKIND_COMPOSITE_TYPE)
 2930 sfrost@snowman.net       7046                 :            152 :             tblinfo[i].dobj.dump = DUMP_COMPONENT_NONE;
                               7047                 :                :         else
                               7048                 :          39371 :             selectDumpableTable(&tblinfo[i], fout);
                               7049                 :                : 
                               7050                 :                :         /*
                               7051                 :                :          * Now, consider the table "interesting" if we need to dump its
                               7052                 :                :          * definition or its data.  Later on, we'll skip a lot of data
                               7053                 :                :          * collection for uninteresting tables.
                               7054                 :                :          *
                               7055                 :                :          * Note: the "interesting" flag will also be set by flagInhTables for
                               7056                 :                :          * parents of interesting tables, so that we collect necessary
                               7057                 :                :          * inheritance info even when the parents are not themselves being
                               7058                 :                :          * dumped.  This is the main reason why we need an "interesting" flag
                               7059                 :                :          * that's separate from the components-to-dump bitmask.
                               7060                 :                :          */
  860 tgl@sss.pgh.pa.us        7061                 :          39523 :         tblinfo[i].interesting = (tblinfo[i].dobj.dump &
                               7062                 :                :                                   (DUMP_COMPONENT_DEFINITION |
                               7063                 :          39523 :                                    DUMP_COMPONENT_DATA)) != 0;
                               7064                 :                : 
  908                          7065                 :          39523 :         tblinfo[i].dummy_view = false;  /* might get set during sort */
                               7066                 :          39523 :         tblinfo[i].postponed_def = false;   /* might get set during sort */
                               7067                 :                : 
                               7068                 :                :         /* Tables have data */
  860                          7069                 :          39523 :         tblinfo[i].dobj.components |= DUMP_COMPONENT_DATA;
                               7070                 :                : 
                               7071                 :                :         /* Mark whether table has an ACL */
                               7072         [ +  + ]:          39523 :         if (!PQgetisnull(res, i, i_relacl))
                               7073                 :          32378 :             tblinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               7074                 :          39523 :         tblinfo[i].hascolumnACLs = false;   /* may get set later */
                               7075                 :                : 
                               7076                 :                :         /*
                               7077                 :                :          * Read-lock target tables to make sure they aren't DROPPED or altered
                               7078                 :                :          * in schema before we get around to dumping them.
                               7079                 :                :          *
                               7080                 :                :          * Note that we don't explicitly lock parents of the target tables; we
                               7081                 :                :          * assume our lock on the child is enough to prevent schema
                               7082                 :                :          * alterations to parent tables.
                               7083                 :                :          *
                               7084                 :                :          * NOTE: it'd be kinda nice to lock other relations too, not only
                               7085                 :                :          * plain or partitioned tables, but the backend doesn't presently
                               7086                 :                :          * allow that.
                               7087                 :                :          *
                               7088                 :                :          * We only need to lock the table for certain components; see
                               7089                 :                :          * pg_dump.h
                               7090                 :                :          */
                               7091         [ +  + ]:          39523 :         if ((tblinfo[i].dobj.dump & DUMP_COMPONENTS_REQUIRING_LOCK) &&
 1255                          7092         [ +  + ]:           5981 :             (tblinfo[i].relkind == RELKIND_RELATION ||
  860                          7093         [ +  + ]:           1698 :              tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
                               7094                 :                :         {
                               7095                 :                :             /*
                               7096                 :                :              * Tables are locked in batches.  When dumping from a remote
                               7097                 :                :              * server this can save a significant amount of time by reducing
                               7098                 :                :              * the number of round trips.
                               7099                 :                :              */
  467                          7100         [ +  + ]:           4807 :             if (query->len == 0)
                               7101                 :            100 :                 appendPQExpBuffer(query, "LOCK TABLE %s",
                               7102                 :            100 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7103                 :                :             else
                               7104                 :                :             {
                               7105                 :           4707 :                 appendPQExpBuffer(query, ", %s",
                               7106                 :           4707 :                                   fmtQualifiedDumpable(&tblinfo[i]));
                               7107                 :                : 
                               7108                 :                :                 /* Arbitrarily end a batch when query length reaches 100K. */
                               7109         [ -  + ]:           4707 :                 if (query->len >= 100000)
                               7110                 :                :                 {
                               7111                 :                :                     /* Lock another batch of tables. */
  467 tgl@sss.pgh.pa.us        7112                 :UBC           0 :                     appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7113                 :              0 :                     ExecuteSqlStatement(fout, query->data);
                               7114                 :              0 :                     resetPQExpBuffer(query);
                               7115                 :                :                 }
                               7116                 :                :             }
                               7117                 :                :         }
                               7118                 :                :     }
                               7119                 :                : 
  467 tgl@sss.pgh.pa.us        7120         [ +  + ]:CBC         156 :     if (query->len != 0)
                               7121                 :                :     {
                               7122                 :                :         /* Lock the tables in the last batch. */
                               7123                 :            100 :         appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
                               7124                 :            100 :         ExecuteSqlStatement(fout, query->data);
                               7125                 :                :     }
                               7126                 :                : 
 2741                          7127         [ +  + ]:            155 :     if (dopt->lockWaitTimeout)
                               7128                 :                :     {
 4450 rhaas@postgresql.org     7129                 :              2 :         ExecuteSqlStatement(fout, "SET statement_timeout = 0");
                               7130                 :                :     }
                               7131                 :                : 
 8010 tgl@sss.pgh.pa.us        7132                 :            155 :     PQclear(res);
                               7133                 :                : 
 4397                          7134                 :            155 :     destroyPQExpBuffer(query);
                               7135                 :                : 
                               7136                 :            155 :     return tblinfo;
                               7137                 :                : }
                               7138                 :                : 
                               7139                 :                : /*
                               7140                 :                :  * getOwnedSeqs
                               7141                 :                :  *    identify owned sequences and mark them as dumpable if owning table is
                               7142                 :                :  *
                               7143                 :                :  * We used to do this in getTables(), but it's better to do it after the
                               7144                 :                :  * index used by findTableByOid() has been set up.
                               7145                 :                :  */
                               7146                 :                : void
                               7147                 :            155 : getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
                               7148                 :                : {
                               7149                 :                :     int         i;
                               7150                 :                : 
                               7151                 :                :     /*
                               7152                 :                :      * Force sequences that are "owned" by table columns to be dumped whenever
                               7153                 :                :      * their owning table is being dumped.
                               7154                 :                :      */
                               7155         [ +  + ]:          39419 :     for (i = 0; i < numTables; i++)
                               7156                 :                :     {
 6446                          7157                 :          39264 :         TableInfo  *seqinfo = &tblinfo[i];
                               7158                 :                :         TableInfo  *owning_tab;
                               7159                 :                : 
                               7160         [ +  + ]:          39264 :         if (!OidIsValid(seqinfo->owning_tab))
                               7161                 :          38936 :             continue;           /* not an owned sequence */
                               7162                 :                : 
 4397                          7163                 :            328 :         owning_tab = findTableByOid(seqinfo->owning_tab);
 2655 sfrost@snowman.net       7164         [ -  + ]:            328 :         if (owning_tab == NULL)
  737 tgl@sss.pgh.pa.us        7165                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                               7166                 :                :                      seqinfo->owning_tab, seqinfo->dobj.catId.oid);
                               7167                 :                : 
                               7168                 :                :         /*
                               7169                 :                :          * Only dump identity sequences if we're going to dump the table that
                               7170                 :                :          * it belongs to.
                               7171                 :                :          */
 2062 michael@paquier.xyz      7172         [ +  + ]:CBC         328 :         if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE &&
                               7173         [ +  + ]:             26 :             seqinfo->is_identity_sequence)
                               7174                 :                :         {
                               7175                 :              7 :             seqinfo->dobj.dump = DUMP_COMPONENT_NONE;
                               7176                 :              7 :             continue;
                               7177                 :                :         }
                               7178                 :                : 
                               7179                 :                :         /*
                               7180                 :                :          * Otherwise we need to dump the components that are being dumped for
                               7181                 :                :          * the table and any components which the sequence is explicitly
                               7182                 :                :          * marked with.
                               7183                 :                :          *
                               7184                 :                :          * We can't simply use the set of components which are being dumped
                               7185                 :                :          * for the table as the table might be in an extension (and only the
                               7186                 :                :          * non-extension components, eg: ACLs if changed, security labels, and
                               7187                 :                :          * policies, are being dumped) while the sequence is not (and
                               7188                 :                :          * therefore the definition and other components should also be
                               7189                 :                :          * dumped).
                               7190                 :                :          *
                               7191                 :                :          * If the sequence is part of the extension then it should be properly
                               7192                 :                :          * marked by checkExtensionMembership() and this will be a no-op as
                               7193                 :                :          * the table will be equivalently marked.
                               7194                 :                :          */
 2814 sfrost@snowman.net       7195                 :            321 :         seqinfo->dobj.dump = seqinfo->dobj.dump | owning_tab->dobj.dump;
                               7196                 :                : 
                               7197         [ +  + ]:            321 :         if (seqinfo->dobj.dump != DUMP_COMPONENT_NONE)
 4397 tgl@sss.pgh.pa.us        7198                 :            304 :             seqinfo->interesting = true;
                               7199                 :                :     }
10141 scrappy@hub.org          7200                 :            155 : }
                               7201                 :                : 
                               7202                 :                : /*
                               7203                 :                :  * getInherits
                               7204                 :                :  *    read all the inheritance information
                               7205                 :                :  * from the system catalogs return them in the InhInfo* structure
                               7206                 :                :  *
                               7207                 :                :  * numInherits is set to the number of pairs read in
                               7208                 :                :  */
                               7209                 :                : InhInfo *
 4451 rhaas@postgresql.org     7210                 :            155 : getInherits(Archive *fout, int *numInherits)
                               7211                 :                : {
                               7212                 :                :     PGresult   *res;
                               7213                 :                :     int         ntups;
                               7214                 :                :     int         i;
 8768 bruce@momjian.us         7215                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               7216                 :                :     InhInfo    *inhinfo;
                               7217                 :                : 
                               7218                 :                :     int         i_inhrelid;
                               7219                 :                :     int         i_inhparent;
                               7220                 :                : 
                               7221                 :                :     /* find all the inheritance information */
 2537 sfrost@snowman.net       7222                 :            155 :     appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
                               7223                 :                : 
 4450 rhaas@postgresql.org     7224                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7225                 :                : 
 9716 bruce@momjian.us         7226                 :            155 :     ntups = PQntuples(res);
                               7227                 :                : 
                               7228                 :            155 :     *numInherits = ntups;
                               7229                 :                : 
 4524                          7230                 :            155 :     inhinfo = (InhInfo *) pg_malloc(ntups * sizeof(InhInfo));
                               7231                 :                : 
 8910                          7232                 :            155 :     i_inhrelid = PQfnumber(res, "inhrelid");
 9716                          7233                 :            155 :     i_inhparent = PQfnumber(res, "inhparent");
                               7234                 :                : 
                               7235         [ +  + ]:           2504 :     for (i = 0; i < ntups; i++)
                               7236                 :                :     {
 7435 tgl@sss.pgh.pa.us        7237                 :           2349 :         inhinfo[i].inhrelid = atooid(PQgetvalue(res, i, i_inhrelid));
                               7238                 :           2349 :         inhinfo[i].inhparent = atooid(PQgetvalue(res, i, i_inhparent));
                               7239                 :                :     }
                               7240                 :                : 
 9716 bruce@momjian.us         7241                 :            155 :     PQclear(res);
                               7242                 :                : 
 8290 tgl@sss.pgh.pa.us        7243                 :            155 :     destroyPQExpBuffer(query);
                               7244                 :                : 
 9716 bruce@momjian.us         7245                 :            155 :     return inhinfo;
                               7246                 :                : }
                               7247                 :                : 
                               7248                 :                : /*
                               7249                 :                :  * getPartitioningInfo
                               7250                 :                :  *    get information about partitioning
                               7251                 :                :  *
                               7252                 :                :  * For the most part, we only collect partitioning info about tables we
                               7253                 :                :  * intend to dump.  However, this function has to consider all partitioned
                               7254                 :                :  * tables in the database, because we need to know about parents of partitions
                               7255                 :                :  * we are going to dump even if the parents themselves won't be dumped.
                               7256                 :                :  *
                               7257                 :                :  * Specifically, what we need to know is whether each partitioned table
                               7258                 :                :  * has an "unsafe" partitioning scheme that requires us to force
                               7259                 :                :  * load-via-partition-root mode for its children.  Currently the only case
                               7260                 :                :  * for which we force that is hash partitioning on enum columns, since the
                               7261                 :                :  * hash codes depend on enum value OIDs which won't be replicated across
                               7262                 :                :  * dump-and-reload.  There are other cases in which load-via-partition-root
                               7263                 :                :  * might be necessary, but we expect users to cope with them.
                               7264                 :                :  */
                               7265                 :                : void
  394 tgl@sss.pgh.pa.us        7266                 :            155 : getPartitioningInfo(Archive *fout)
                               7267                 :                : {
                               7268                 :                :     PQExpBuffer query;
                               7269                 :                :     PGresult   *res;
                               7270                 :                :     int         ntups;
                               7271                 :                : 
                               7272                 :                :     /* hash partitioning didn't exist before v11 */
                               7273         [ -  + ]:            155 :     if (fout->remoteVersion < 110000)
  394 tgl@sss.pgh.pa.us        7274                 :UBC           0 :         return;
                               7275                 :                :     /* needn't bother if schema-only dump */
  394 tgl@sss.pgh.pa.us        7276         [ +  + ]:CBC         155 :     if (fout->dopt->schemaOnly)
                               7277                 :             16 :         return;
                               7278                 :                : 
                               7279                 :            139 :     query = createPQExpBuffer();
                               7280                 :                : 
                               7281                 :                :     /*
                               7282                 :                :      * Unsafe partitioning schemes are exactly those for which hash enum_ops
                               7283                 :                :      * appears among the partition opclasses.  We needn't check partstrat.
                               7284                 :                :      *
                               7285                 :                :      * Note that this query may well retrieve info about tables we aren't
                               7286                 :                :      * going to dump and hence have no lock on.  That's okay since we need not
                               7287                 :                :      * invoke any unsafe server-side functions.
                               7288                 :                :      */
                               7289                 :            139 :     appendPQExpBufferStr(query,
                               7290                 :                :                          "SELECT partrelid FROM pg_partitioned_table WHERE\n"
                               7291                 :                :                          "(SELECT c.oid FROM pg_opclass c JOIN pg_am a "
                               7292                 :                :                          "ON c.opcmethod = a.oid\n"
                               7293                 :                :                          "WHERE opcname = 'enum_ops' "
                               7294                 :                :                          "AND opcnamespace = 'pg_catalog'::regnamespace "
                               7295                 :                :                          "AND amname = 'hash') = ANY(partclass)");
                               7296                 :                : 
                               7297                 :            139 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7298                 :                : 
                               7299                 :            139 :     ntups = PQntuples(res);
                               7300                 :                : 
                               7301         [ +  + ]:            141 :     for (int i = 0; i < ntups; i++)
                               7302                 :                :     {
                               7303                 :              2 :         Oid         tabrelid = atooid(PQgetvalue(res, i, 0));
                               7304                 :                :         TableInfo  *tbinfo;
                               7305                 :                : 
                               7306                 :              2 :         tbinfo = findTableByOid(tabrelid);
                               7307         [ -  + ]:              2 :         if (tbinfo == NULL)
  394 tgl@sss.pgh.pa.us        7308                 :UBC           0 :             pg_fatal("failed sanity check, table OID %u appearing in pg_partitioned_table not found",
                               7309                 :                :                      tabrelid);
  394 tgl@sss.pgh.pa.us        7310                 :CBC           2 :         tbinfo->unsafe_partitions = true;
                               7311                 :                :     }
                               7312                 :                : 
                               7313                 :            139 :     PQclear(res);
                               7314                 :                : 
                               7315                 :            139 :     destroyPQExpBuffer(query);
                               7316                 :                : }
                               7317                 :                : 
                               7318                 :                : /*
                               7319                 :                :  * getIndexes
                               7320                 :                :  *    get information about every index on a dumpable table
                               7321                 :                :  *
                               7322                 :                :  * Note: index data is not returned directly to the caller, but it
                               7323                 :                :  * does get entered into the DumpableObject tables.
                               7324                 :                :  */
                               7325                 :                : void
 4451 rhaas@postgresql.org     7326                 :            155 : getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                               7327                 :                : {
 7435 tgl@sss.pgh.pa.us        7328                 :            155 :     PQExpBuffer query = createPQExpBuffer();
  860                          7329                 :            155 :     PQExpBuffer tbloids = createPQExpBuffer();
                               7330                 :                :     PGresult   *res;
                               7331                 :                :     int         ntups;
                               7332                 :                :     int         curtblindx;
                               7333                 :                :     IndxInfo   *indxinfo;
                               7334                 :                :     int         i_tableoid,
                               7335                 :                :                 i_oid,
                               7336                 :                :                 i_indrelid,
                               7337                 :                :                 i_indexname,
                               7338                 :                :                 i_parentidx,
                               7339                 :                :                 i_indexdef,
                               7340                 :                :                 i_indnkeyatts,
                               7341                 :                :                 i_indnatts,
                               7342                 :                :                 i_indkey,
                               7343                 :                :                 i_indisclustered,
                               7344                 :                :                 i_indisreplident,
                               7345                 :                :                 i_indnullsnotdistinct,
                               7346                 :                :                 i_contype,
                               7347                 :                :                 i_conname,
                               7348                 :                :                 i_condeferrable,
                               7349                 :                :                 i_condeferred,
                               7350                 :                :                 i_conperiod,
                               7351                 :                :                 i_contableoid,
                               7352                 :                :                 i_conoid,
                               7353                 :                :                 i_condef,
                               7354                 :                :                 i_tablespace,
                               7355                 :                :                 i_indreloptions,
                               7356                 :                :                 i_indstatcols,
                               7357                 :                :                 i_indstatvals;
                               7358                 :                : 
                               7359                 :                :     /*
                               7360                 :                :      * We want to perform just one query against pg_index.  However, we
                               7361                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               7362                 :                :      * the client side, because some of the server-side functions we need
                               7363                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               7364                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               7365                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               7366                 :                :      */
                               7367                 :            155 :     appendPQExpBufferChar(tbloids, '{');
                               7368         [ +  + ]:          39419 :     for (int i = 0; i < numTables; i++)
                               7369                 :                :     {
 7435                          7370                 :          39264 :         TableInfo  *tbinfo = &tblinfo[i];
                               7371                 :                : 
 4060 kgrittn@postgresql.o     7372         [ +  + ]:          39264 :         if (!tbinfo->hasindex)
 7435 tgl@sss.pgh.pa.us        7373                 :          27592 :             continue;
                               7374                 :                : 
                               7375                 :                :         /*
                               7376                 :                :          * We can ignore indexes of uninteresting tables.
                               7377                 :                :          */
  860                          7378         [ +  + ]:          11672 :         if (!tbinfo->interesting)
 7435                          7379                 :           9942 :             continue;
                               7380                 :                : 
                               7381                 :                :         /* OK, we need info for this table */
  860                          7382         [ +  + ]:           1730 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               7383                 :           1653 :             appendPQExpBufferChar(tbloids, ',');
                               7384                 :           1730 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               7385                 :                :     }
                               7386                 :            155 :     appendPQExpBufferChar(tbloids, '}');
                               7387                 :                : 
  586 drowley@postgresql.o     7388                 :            155 :     appendPQExpBufferStr(query,
                               7389                 :                :                          "SELECT t.tableoid, t.oid, i.indrelid, "
                               7390                 :                :                          "t.relname AS indexname, "
                               7391                 :                :                          "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                               7392                 :                :                          "i.indkey, i.indisclustered, "
                               7393                 :                :                          "c.contype, c.conname, "
                               7394                 :                :                          "c.condeferrable, c.condeferred, "
                               7395                 :                :                          "c.tableoid AS contableoid, "
                               7396                 :                :                          "c.oid AS conoid, "
                               7397                 :                :                          "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
                               7398                 :                :                          "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
                               7399                 :                :                          "t.reloptions AS indreloptions, ");
                               7400                 :                : 
                               7401                 :                : 
  846 peter@eisentraut.org     7402         [ +  - ]:            155 :     if (fout->remoteVersion >= 90400)
  586 drowley@postgresql.o     7403                 :            155 :         appendPQExpBufferStr(query,
                               7404                 :                :                              "i.indisreplident, ");
                               7405                 :                :     else
  586 drowley@postgresql.o     7406                 :UBC           0 :         appendPQExpBufferStr(query,
                               7407                 :                :                              "false AS indisreplident, ");
                               7408                 :                : 
  846 peter@eisentraut.org     7409         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 110000)
  586 drowley@postgresql.o     7410                 :            155 :         appendPQExpBufferStr(query,
                               7411                 :                :                              "inh.inhparent AS parentidx, "
                               7412                 :                :                              "i.indnkeyatts AS indnkeyatts, "
                               7413                 :                :                              "i.indnatts AS indnatts, "
                               7414                 :                :                              "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) "
                               7415                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7416                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7417                 :                :                              "    attstattarget >= 0) AS indstatcols, "
                               7418                 :                :                              "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) "
                               7419                 :                :                              "  FROM pg_catalog.pg_attribute "
                               7420                 :                :                              "  WHERE attrelid = i.indexrelid AND "
                               7421                 :                :                              "    attstattarget >= 0) AS indstatvals, ");
                               7422                 :                :     else
  586 drowley@postgresql.o     7423                 :UBC           0 :         appendPQExpBufferStr(query,
                               7424                 :                :                              "0 AS parentidx, "
                               7425                 :                :                              "i.indnatts AS indnkeyatts, "
                               7426                 :                :                              "i.indnatts AS indnatts, "
                               7427                 :                :                              "'' AS indstatcols, "
                               7428                 :                :                              "'' AS indstatvals, ");
                               7429                 :                : 
  801 peter@eisentraut.org     7430         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 150000)
  586 drowley@postgresql.o     7431                 :            155 :         appendPQExpBufferStr(query,
                               7432                 :                :                              "i.indnullsnotdistinct, ");
                               7433                 :                :     else
  586 drowley@postgresql.o     7434                 :UBC           0 :         appendPQExpBufferStr(query,
                               7435                 :                :                              "false AS indnullsnotdistinct, ");
                               7436                 :                : 
   81 peter@eisentraut.org     7437         [ +  - ]:GNC         155 :     if (fout->remoteVersion >= 170000)
                               7438                 :            155 :         appendPQExpBufferStr(query,
                               7439                 :                :                              "c.conperiod ");
                               7440                 :                :     else
   81 peter@eisentraut.org     7441                 :UNC           0 :         appendPQExpBufferStr(query,
                               7442                 :                :                              "NULL AS conperiod ");
                               7443                 :                : 
                               7444                 :                :     /*
                               7445                 :                :      * The point of the messy-looking outer join is to find a constraint that
                               7446                 :                :      * is related by an internal dependency link to the index. If we find one,
                               7447                 :                :      * create a CONSTRAINT entry linked to the INDEX entry.  We assume an
                               7448                 :                :      * index won't have more than one internal dependency.
                               7449                 :                :      *
                               7450                 :                :      * Note: the check on conrelid is redundant, but useful because that
                               7451                 :                :      * column is indexed while conindid is not.
                               7452                 :                :      */
  860 tgl@sss.pgh.pa.us        7453         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 110000)
                               7454                 :                :     {
                               7455                 :            155 :         appendPQExpBuffer(query,
                               7456                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7457                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               7458                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               7459                 :                :                           "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) "
                               7460                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               7461                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               7462                 :                :                           "i.indexrelid = c.conindid AND "
                               7463                 :                :                           "c.contype IN ('p','u','x')) "
                               7464                 :                :                           "LEFT JOIN pg_catalog.pg_inherits inh "
                               7465                 :                :                           "ON (inh.inhrelid = indexrelid) "
                               7466                 :                :                           "WHERE (i.indisvalid OR t2.relkind = 'p') "
                               7467                 :                :                           "AND i.indisready "
                               7468                 :                :                           "ORDER BY i.indrelid, indexname",
                               7469                 :                :                           tbloids->data);
                               7470                 :                :     }
                               7471                 :                :     else
                               7472                 :                :     {
                               7473                 :                :         /*
                               7474                 :                :          * the test on indisready is necessary in 9.2, and harmless in
                               7475                 :                :          * earlier/later versions
                               7476                 :                :          */
  860 tgl@sss.pgh.pa.us        7477                 :UBC           0 :         appendPQExpBuffer(query,
                               7478                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7479                 :                :                           "JOIN pg_catalog.pg_index i ON (src.tbloid = i.indrelid) "
                               7480                 :                :                           "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
                               7481                 :                :                           "LEFT JOIN pg_catalog.pg_constraint c "
                               7482                 :                :                           "ON (i.indrelid = c.conrelid AND "
                               7483                 :                :                           "i.indexrelid = c.conindid AND "
                               7484                 :                :                           "c.contype IN ('p','u','x')) "
                               7485                 :                :                           "WHERE i.indisvalid AND i.indisready "
                               7486                 :                :                           "ORDER BY i.indrelid, indexname",
                               7487                 :                :                           tbloids->data);
                               7488                 :                :     }
                               7489                 :                : 
  860 tgl@sss.pgh.pa.us        7490                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7491                 :                : 
                               7492                 :            155 :     ntups = PQntuples(res);
                               7493                 :                : 
                               7494                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               7495                 :            155 :     i_oid = PQfnumber(res, "oid");
                               7496                 :            155 :     i_indrelid = PQfnumber(res, "indrelid");
                               7497                 :            155 :     i_indexname = PQfnumber(res, "indexname");
                               7498                 :            155 :     i_parentidx = PQfnumber(res, "parentidx");
                               7499                 :            155 :     i_indexdef = PQfnumber(res, "indexdef");
                               7500                 :            155 :     i_indnkeyatts = PQfnumber(res, "indnkeyatts");
                               7501                 :            155 :     i_indnatts = PQfnumber(res, "indnatts");
                               7502                 :            155 :     i_indkey = PQfnumber(res, "indkey");
                               7503                 :            155 :     i_indisclustered = PQfnumber(res, "indisclustered");
                               7504                 :            155 :     i_indisreplident = PQfnumber(res, "indisreplident");
  801 peter@eisentraut.org     7505                 :            155 :     i_indnullsnotdistinct = PQfnumber(res, "indnullsnotdistinct");
  860 tgl@sss.pgh.pa.us        7506                 :            155 :     i_contype = PQfnumber(res, "contype");
                               7507                 :            155 :     i_conname = PQfnumber(res, "conname");
                               7508                 :            155 :     i_condeferrable = PQfnumber(res, "condeferrable");
                               7509                 :            155 :     i_condeferred = PQfnumber(res, "condeferred");
   40 peter@eisentraut.org     7510                 :GNC         155 :     i_conperiod = PQfnumber(res, "conperiod");
  860 tgl@sss.pgh.pa.us        7511                 :CBC         155 :     i_contableoid = PQfnumber(res, "contableoid");
                               7512                 :            155 :     i_conoid = PQfnumber(res, "conoid");
                               7513                 :            155 :     i_condef = PQfnumber(res, "condef");
                               7514                 :            155 :     i_tablespace = PQfnumber(res, "tablespace");
                               7515                 :            155 :     i_indreloptions = PQfnumber(res, "indreloptions");
                               7516                 :            155 :     i_indstatcols = PQfnumber(res, "indstatcols");
                               7517                 :            155 :     i_indstatvals = PQfnumber(res, "indstatvals");
                               7518                 :                : 
                               7519                 :            155 :     indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo));
                               7520                 :                : 
                               7521                 :                :     /*
                               7522                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               7523                 :                :      * j is handled by the inner loop.
                               7524                 :                :      */
                               7525                 :            155 :     curtblindx = -1;
                               7526         [ +  + ]:           1881 :     for (int j = 0; j < ntups;)
                               7527                 :                :     {
                               7528                 :           1726 :         Oid         indrelid = atooid(PQgetvalue(res, j, i_indrelid));
                               7529                 :           1726 :         TableInfo  *tbinfo = NULL;
                               7530                 :                :         int         numinds;
                               7531                 :                : 
                               7532                 :                :         /* Count rows for this table */
                               7533         [ +  + ]:           2222 :         for (numinds = 1; numinds < ntups - j; numinds++)
                               7534         [ +  + ]:           2145 :             if (atooid(PQgetvalue(res, j + numinds, i_indrelid)) != indrelid)
                               7535                 :           1649 :                 break;
                               7536                 :                : 
                               7537                 :                :         /*
                               7538                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               7539                 :                :          * order.
                               7540                 :                :          */
                               7541         [ +  - ]:          22221 :         while (++curtblindx < numTables)
                               7542                 :                :         {
                               7543                 :          22221 :             tbinfo = &tblinfo[curtblindx];
                               7544         [ +  + ]:          22221 :             if (tbinfo->dobj.catId.oid == indrelid)
                               7545                 :           1726 :                 break;
                               7546                 :                :         }
                               7547         [ -  + ]:           1726 :         if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        7548                 :UBC           0 :             pg_fatal("unrecognized table OID %u", indrelid);
                               7549                 :                :         /* cross-check that we only got requested tables */
  860 tgl@sss.pgh.pa.us        7550         [ +  - ]:CBC        1726 :         if (!tbinfo->hasindex ||
                               7551         [ -  + ]:           1726 :             !tbinfo->interesting)
  737 tgl@sss.pgh.pa.us        7552                 :UBC           0 :             pg_fatal("unexpected index data for table \"%s\"",
                               7553                 :                :                      tbinfo->dobj.name);
                               7554                 :                : 
                               7555                 :                :         /* Save data for this table */
  860 tgl@sss.pgh.pa.us        7556                 :CBC        1726 :         tbinfo->indexes = indxinfo + j;
                               7557                 :           1726 :         tbinfo->numIndexes = numinds;
                               7558                 :                : 
                               7559         [ +  + ]:           3948 :         for (int c = 0; c < numinds; c++, j++)
                               7560                 :                :         {
                               7561                 :                :             char        contype;
                               7562                 :                : 
 7435                          7563                 :           2222 :             indxinfo[j].dobj.objType = DO_INDEX;
                               7564                 :           2222 :             indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               7565                 :           2222 :             indxinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               7566                 :           2222 :             AssignDumpId(&indxinfo[j].dobj);
 2277 alvherre@alvh.no-ip.     7567                 :           2222 :             indxinfo[j].dobj.dump = tbinfo->dobj.dump;
 4524 bruce@momjian.us         7568                 :           2222 :             indxinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_indexname));
 7347 tgl@sss.pgh.pa.us        7569                 :           2222 :             indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7435                          7570                 :           2222 :             indxinfo[j].indextable = tbinfo;
 4524 bruce@momjian.us         7571                 :           2222 :             indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef));
 2189 heikki.linnakangas@i     7572                 :           2222 :             indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts));
 2199 teodor@sigaev.ru         7573                 :           2222 :             indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
 4524 bruce@momjian.us         7574                 :           2222 :             indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace));
 3025 tgl@sss.pgh.pa.us        7575                 :           2222 :             indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions));
 1944 michael@paquier.xyz      7576                 :           2222 :             indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols));
                               7577                 :           2222 :             indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals));
 2199 teodor@sigaev.ru         7578                 :           2222 :             indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid));
 7435 tgl@sss.pgh.pa.us        7579                 :           2222 :             parseOidArray(PQgetvalue(res, j, i_indkey),
 2199 teodor@sigaev.ru         7580                 :           2222 :                           indxinfo[j].indkeys, indxinfo[j].indnattrs);
 7435 tgl@sss.pgh.pa.us        7581                 :           2222 :             indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
 3810 rhaas@postgresql.org     7582                 :           2222 :             indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
  801 peter@eisentraut.org     7583                 :           2222 :             indxinfo[j].indnullsnotdistinct = (PQgetvalue(res, j, i_indnullsnotdistinct)[0] == 't');
 2277 alvherre@alvh.no-ip.     7584                 :           2222 :             indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx));
 1431 tgl@sss.pgh.pa.us        7585                 :           2222 :             indxinfo[j].partattaches = (SimplePtrList)
                               7586                 :                :             {
                               7587                 :                :                 NULL, NULL
                               7588                 :                :             };
 7435                          7589                 :           2222 :             contype = *(PQgetvalue(res, j, i_contype));
                               7590                 :                : 
 5242                          7591   [ +  +  +  +  :           2222 :             if (contype == 'p' || contype == 'u' || contype == 'x')
                                              +  + ]
 7435                          7592                 :           1211 :             {
                               7593                 :                :                 /*
                               7594                 :                :                  * If we found a constraint matching the index, create an
                               7595                 :                :                  * entry for it.
                               7596                 :                :                  */
                               7597                 :                :                 ConstraintInfo *constrinfo;
                               7598                 :                : 
  903                          7599                 :           1211 :                 constrinfo = (ConstraintInfo *) pg_malloc(sizeof(ConstraintInfo));
                               7600                 :           1211 :                 constrinfo->dobj.objType = DO_CONSTRAINT;
                               7601                 :           1211 :                 constrinfo->dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               7602                 :           1211 :                 constrinfo->dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               7603                 :           1211 :                 AssignDumpId(&constrinfo->dobj);
                               7604                 :           1211 :                 constrinfo->dobj.dump = tbinfo->dobj.dump;
                               7605                 :           1211 :                 constrinfo->dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               7606                 :           1211 :                 constrinfo->dobj.namespace = tbinfo->dobj.namespace;
                               7607                 :           1211 :                 constrinfo->contable = tbinfo;
                               7608                 :           1211 :                 constrinfo->condomain = NULL;
                               7609                 :           1211 :                 constrinfo->contype = contype;
 5242                          7610         [ +  + ]:           1211 :                 if (contype == 'x')
  903                          7611                 :             10 :                     constrinfo->condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               7612                 :                :                 else
                               7613                 :           1201 :                     constrinfo->condef = NULL;
                               7614                 :           1211 :                 constrinfo->confrelid = InvalidOid;
                               7615                 :           1211 :                 constrinfo->conindex = indxinfo[j].dobj.dumpId;
                               7616                 :           1211 :                 constrinfo->condeferrable = *(PQgetvalue(res, j, i_condeferrable)) == 't';
                               7617                 :           1211 :                 constrinfo->condeferred = *(PQgetvalue(res, j, i_condeferred)) == 't';
   40 peter@eisentraut.org     7618                 :GNC        1211 :                 constrinfo->conperiod = *(PQgetvalue(res, j, i_conperiod)) == 't';
  903 tgl@sss.pgh.pa.us        7619                 :CBC        1211 :                 constrinfo->conislocal = true;
                               7620                 :           1211 :                 constrinfo->separate = true;
                               7621                 :                : 
                               7622                 :           1211 :                 indxinfo[j].indexconstraint = constrinfo->dobj.dumpId;
                               7623                 :                :             }
                               7624                 :                :             else
                               7625                 :                :             {
                               7626                 :                :                 /* Plain secondary index */
 7435                          7627                 :           1011 :                 indxinfo[j].indexconstraint = 0;
                               7628                 :                :             }
                               7629                 :                :         }
                               7630                 :                :     }
                               7631                 :                : 
  860                          7632                 :            155 :     PQclear(res);
                               7633                 :                : 
 7435                          7634                 :            155 :     destroyPQExpBuffer(query);
  860                          7635                 :            155 :     destroyPQExpBuffer(tbloids);
 7435                          7636                 :            155 : }
                               7637                 :                : 
                               7638                 :                : /*
                               7639                 :                :  * getExtendedStatistics
                               7640                 :                :  *    get information about extended-statistics objects.
                               7641                 :                :  *
                               7642                 :                :  * Note: extended statistics data is not returned directly to the caller, but
                               7643                 :                :  * it does get entered into the DumpableObject tables.
                               7644                 :                :  */
                               7645                 :                : void
 2254                          7646                 :            155 : getExtendedStatistics(Archive *fout)
                               7647                 :                : {
                               7648                 :                :     PQExpBuffer query;
                               7649                 :                :     PGresult   *res;
                               7650                 :                :     StatsExtInfo *statsextinfo;
                               7651                 :                :     int         ntups;
                               7652                 :                :     int         i_tableoid;
                               7653                 :                :     int         i_oid;
                               7654                 :                :     int         i_stxname;
                               7655                 :                :     int         i_stxnamespace;
                               7656                 :                :     int         i_stxowner;
                               7657                 :                :     int         i_stxrelid;
                               7658                 :                :     int         i_stattarget;
                               7659                 :                :     int         i;
                               7660                 :                : 
                               7661                 :                :     /* Extended statistics were new in v10 */
 2578 alvherre@alvh.no-ip.     7662         [ -  + ]:            155 :     if (fout->remoteVersion < 100000)
 2578 alvherre@alvh.no-ip.     7663                 :UBC           0 :         return;
                               7664                 :                : 
 2578 alvherre@alvh.no-ip.     7665                 :CBC         155 :     query = createPQExpBuffer();
                               7666                 :                : 
 1678 tomas.vondra@postgre     7667         [ -  + ]:            155 :     if (fout->remoteVersion < 130000)
  586 drowley@postgresql.o     7668                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               7669                 :                :                              "stxnamespace, stxowner, stxrelid, NULL AS stxstattarget "
                               7670                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               7671                 :                :     else
  586 drowley@postgresql.o     7672                 :CBC         155 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, stxname, "
                               7673                 :                :                              "stxnamespace, stxowner, stxrelid, stxstattarget "
                               7674                 :                :                              "FROM pg_catalog.pg_statistic_ext");
                               7675                 :                : 
 2254 tgl@sss.pgh.pa.us        7676                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7677                 :                : 
                               7678                 :            155 :     ntups = PQntuples(res);
                               7679                 :                : 
                               7680                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               7681                 :            155 :     i_oid = PQfnumber(res, "oid");
                               7682                 :            155 :     i_stxname = PQfnumber(res, "stxname");
                               7683                 :            155 :     i_stxnamespace = PQfnumber(res, "stxnamespace");
  835                          7684                 :            155 :     i_stxowner = PQfnumber(res, "stxowner");
  107                          7685                 :            155 :     i_stxrelid = PQfnumber(res, "stxrelid");
 1678 tomas.vondra@postgre     7686                 :            155 :     i_stattarget = PQfnumber(res, "stxstattarget");
                               7687                 :                : 
 2254 tgl@sss.pgh.pa.us        7688                 :            155 :     statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo));
                               7689                 :                : 
                               7690         [ +  + ]:            313 :     for (i = 0; i < ntups; i++)
                               7691                 :                :     {
                               7692                 :            158 :         statsextinfo[i].dobj.objType = DO_STATSEXT;
                               7693                 :            158 :         statsextinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               7694                 :            158 :         statsextinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               7695                 :            158 :         AssignDumpId(&statsextinfo[i].dobj);
                               7696                 :            158 :         statsextinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_stxname));
                               7697                 :            316 :         statsextinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     7698                 :            158 :             findNamespace(atooid(PQgetvalue(res, i, i_stxnamespace)));
  835 tgl@sss.pgh.pa.us        7699                 :            158 :         statsextinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_stxowner));
  107                          7700                 :            316 :         statsextinfo[i].stattable =
                               7701                 :            158 :             findTableByOid(atooid(PQgetvalue(res, i, i_stxrelid)));
   28 peter@eisentraut.org     7702         [ +  + ]:GNC         158 :         if (PQgetisnull(res, i, i_stattarget))
                               7703                 :            112 :             statsextinfo[i].stattarget = -1;
                               7704                 :                :         else
                               7705                 :             46 :             statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget));
                               7706                 :                : 
                               7707                 :                :         /* Decide whether we want to dump it */
  107 tgl@sss.pgh.pa.us        7708                 :CBC         158 :         selectDumpableStatisticsObject(&(statsextinfo[i]), fout);
                               7709                 :                :     }
                               7710                 :                : 
 2254                          7711                 :            155 :     PQclear(res);
 2578 alvherre@alvh.no-ip.     7712                 :            155 :     destroyPQExpBuffer(query);
                               7713                 :                : }
                               7714                 :                : 
                               7715                 :                : /*
                               7716                 :                :  * getConstraints
                               7717                 :                :  *
                               7718                 :                :  * Get info about constraints on dumpable tables.
                               7719                 :                :  *
                               7720                 :                :  * Currently handles foreign keys only.
                               7721                 :                :  * Unique and primary key constraints are handled with indexes,
                               7722                 :                :  * while check constraints are processed in getTableAttrs().
                               7723                 :                :  */
                               7724                 :                : void
 4451 rhaas@postgresql.org     7725                 :            155 : getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
                               7726                 :                : {
  860 tgl@sss.pgh.pa.us        7727                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               7728                 :            155 :     PQExpBuffer tbloids = createPQExpBuffer();
                               7729                 :                :     PGresult   *res;
                               7730                 :                :     int         ntups;
                               7731                 :                :     int         curtblindx;
                               7732                 :            155 :     TableInfo  *tbinfo = NULL;
                               7733                 :                :     ConstraintInfo *constrinfo;
                               7734                 :                :     int         i_contableoid,
                               7735                 :                :                 i_conoid,
                               7736                 :                :                 i_conrelid,
                               7737                 :                :                 i_conname,
                               7738                 :                :                 i_confrelid,
                               7739                 :                :                 i_conindid,
                               7740                 :                :                 i_condef;
                               7741                 :                : 
                               7742                 :                :     /*
                               7743                 :                :      * We want to perform just one query against pg_constraint.  However, we
                               7744                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               7745                 :                :      * the client side, because some of the server-side functions we need
                               7746                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               7747                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               7748                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               7749                 :                :      */
                               7750                 :            155 :     appendPQExpBufferChar(tbloids, '{');
                               7751         [ +  + ]:          39419 :     for (int i = 0; i < numTables; i++)
                               7752                 :                :     {
  603 drowley@postgresql.o     7753                 :          39264 :         TableInfo  *tinfo = &tblinfo[i];
                               7754                 :                : 
                               7755                 :                :         /*
                               7756                 :                :          * For partitioned tables, foreign keys have no triggers so they must
                               7757                 :                :          * be included anyway in case some foreign keys are defined.
                               7758                 :                :          */
                               7759         [ +  + ]:          39264 :         if ((!tinfo->hastriggers &&
                               7760         [ +  + ]:          38348 :              tinfo->relkind != RELKIND_PARTITIONED_TABLE) ||
                               7761         [ +  + ]:           1258 :             !(tinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7435 tgl@sss.pgh.pa.us        7762                 :          38071 :             continue;
                               7763                 :                : 
                               7764                 :                :         /* OK, we need info for this table */
  860                          7765         [ +  + ]:           1193 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               7766                 :           1139 :             appendPQExpBufferChar(tbloids, ',');
  603 drowley@postgresql.o     7767                 :           1193 :         appendPQExpBuffer(tbloids, "%u", tinfo->dobj.catId.oid);
                               7768                 :                :     }
  860 tgl@sss.pgh.pa.us        7769                 :            155 :     appendPQExpBufferChar(tbloids, '}');
                               7770                 :                : 
                               7771                 :            155 :     appendPQExpBufferStr(query,
                               7772                 :                :                          "SELECT c.tableoid, c.oid, "
                               7773                 :                :                          "conrelid, conname, confrelid, ");
                               7774         [ +  - ]:            155 :     if (fout->remoteVersion >= 110000)
                               7775                 :            155 :         appendPQExpBufferStr(query, "conindid, ");
                               7776                 :                :     else
  860 tgl@sss.pgh.pa.us        7777                 :UBC           0 :         appendPQExpBufferStr(query, "0 AS conindid, ");
  860 tgl@sss.pgh.pa.us        7778                 :CBC         155 :     appendPQExpBuffer(query,
                               7779                 :                :                       "pg_catalog.pg_get_constraintdef(c.oid) AS condef\n"
                               7780                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               7781                 :                :                       "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               7782                 :                :                       "WHERE contype = 'f' ",
                               7783                 :                :                       tbloids->data);
                               7784         [ +  - ]:            155 :     if (fout->remoteVersion >= 110000)
                               7785                 :            155 :         appendPQExpBufferStr(query,
                               7786                 :                :                              "AND conparentid = 0 ");
                               7787                 :            155 :     appendPQExpBufferStr(query,
                               7788                 :                :                          "ORDER BY conrelid, conname");
                               7789                 :                : 
                               7790                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7791                 :                : 
                               7792                 :            155 :     ntups = PQntuples(res);
                               7793                 :                : 
                               7794                 :            155 :     i_contableoid = PQfnumber(res, "tableoid");
                               7795                 :            155 :     i_conoid = PQfnumber(res, "oid");
                               7796                 :            155 :     i_conrelid = PQfnumber(res, "conrelid");
                               7797                 :            155 :     i_conname = PQfnumber(res, "conname");
                               7798                 :            155 :     i_confrelid = PQfnumber(res, "confrelid");
                               7799                 :            155 :     i_conindid = PQfnumber(res, "conindid");
                               7800                 :            155 :     i_condef = PQfnumber(res, "condef");
                               7801                 :                : 
                               7802                 :            155 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
                               7803                 :                : 
                               7804                 :            155 :     curtblindx = -1;
                               7805         [ +  + ]:            333 :     for (int j = 0; j < ntups; j++)
                               7806                 :                :     {
                               7807                 :            178 :         Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               7808                 :                :         TableInfo  *reftable;
                               7809                 :                : 
                               7810                 :                :         /*
                               7811                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               7812                 :                :          * order.
                               7813                 :                :          */
                               7814   [ +  +  +  + ]:            178 :         if (tbinfo == NULL || tbinfo->dobj.catId.oid != conrelid)
                               7815                 :                :         {
                               7816         [ +  - ]:          13252 :             while (++curtblindx < numTables)
                               7817                 :                :             {
                               7818                 :          13252 :                 tbinfo = &tblinfo[curtblindx];
                               7819         [ +  + ]:          13252 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               7820                 :            168 :                     break;
                               7821                 :                :             }
                               7822         [ -  + ]:            168 :             if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        7823                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               7824                 :                :         }
                               7825                 :                : 
  860 tgl@sss.pgh.pa.us        7826                 :CBC         178 :         constrinfo[j].dobj.objType = DO_FK_CONSTRAINT;
                               7827                 :            178 :         constrinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_contableoid));
                               7828                 :            178 :         constrinfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_conoid));
                               7829                 :            178 :         AssignDumpId(&constrinfo[j].dobj);
                               7830                 :            178 :         constrinfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
                               7831                 :            178 :         constrinfo[j].dobj.namespace = tbinfo->dobj.namespace;
                               7832                 :            178 :         constrinfo[j].contable = tbinfo;
                               7833                 :            178 :         constrinfo[j].condomain = NULL;
                               7834                 :            178 :         constrinfo[j].contype = 'f';
                               7835                 :            178 :         constrinfo[j].condef = pg_strdup(PQgetvalue(res, j, i_condef));
                               7836                 :            178 :         constrinfo[j].confrelid = atooid(PQgetvalue(res, j, i_confrelid));
                               7837                 :            178 :         constrinfo[j].conindex = 0;
                               7838                 :            178 :         constrinfo[j].condeferrable = false;
                               7839                 :            178 :         constrinfo[j].condeferred = false;
                               7840                 :            178 :         constrinfo[j].conislocal = true;
                               7841                 :            178 :         constrinfo[j].separate = true;
                               7842                 :                : 
                               7843                 :                :         /*
                               7844                 :                :          * Restoring an FK that points to a partitioned table requires that
                               7845                 :                :          * all partition indexes have been attached beforehand. Ensure that
                               7846                 :                :          * happens by making the constraint depend on each index partition
                               7847                 :                :          * attach object.
                               7848                 :                :          */
                               7849                 :            178 :         reftable = findTableByOid(constrinfo[j].confrelid);
                               7850   [ +  -  +  + ]:            178 :         if (reftable && reftable->relkind == RELKIND_PARTITIONED_TABLE)
                               7851                 :                :         {
                               7852                 :             20 :             Oid         indexOid = atooid(PQgetvalue(res, j, i_conindid));
                               7853                 :                : 
                               7854         [ +  - ]:             20 :             if (indexOid != InvalidOid)
                               7855                 :                :             {
                               7856         [ +  - ]:             20 :                 for (int k = 0; k < reftable->numIndexes; k++)
                               7857                 :                :                 {
                               7858                 :                :                     IndxInfo   *refidx;
                               7859                 :                : 
                               7860                 :                :                     /* not our index? */
                               7861         [ -  + ]:             20 :                     if (reftable->indexes[k].dobj.catId.oid != indexOid)
  860 tgl@sss.pgh.pa.us        7862                 :UBC           0 :                         continue;
                               7863                 :                : 
  860 tgl@sss.pgh.pa.us        7864                 :CBC          20 :                     refidx = &reftable->indexes[k];
                               7865                 :             20 :                     addConstrChildIdxDeps(&constrinfo[j].dobj, refidx);
                               7866                 :             20 :                     break;
                               7867                 :                :                 }
                               7868                 :                :             }
                               7869                 :                :         }
                               7870                 :                :     }
                               7871                 :                : 
                               7872                 :            155 :     PQclear(res);
                               7873                 :                : 
 7435                          7874                 :            155 :     destroyPQExpBuffer(query);
  860                          7875                 :            155 :     destroyPQExpBuffer(tbloids);
 7435                          7876                 :            155 : }
                               7877                 :                : 
                               7878                 :                : /*
                               7879                 :                :  * addConstrChildIdxDeps
                               7880                 :                :  *
                               7881                 :                :  * Recursive subroutine for getConstraints
                               7882                 :                :  *
                               7883                 :                :  * Given an object representing a foreign key constraint and an index on the
                               7884                 :                :  * partitioned table it references, mark the constraint object as dependent
                               7885                 :                :  * on the DO_INDEX_ATTACH object of each index partition, recursively
                               7886                 :                :  * drilling down to their partitions if any.  This ensures that the FK is not
                               7887                 :                :  * restored until the index is fully marked valid.
                               7888                 :                :  */
                               7889                 :                : static void
 1159 peter@eisentraut.org     7890                 :             45 : addConstrChildIdxDeps(DumpableObject *dobj, const IndxInfo *refidx)
                               7891                 :                : {
                               7892                 :                :     SimplePtrListCell *cell;
                               7893                 :                : 
 1339 alvherre@alvh.no-ip.     7894         [ -  + ]:             45 :     Assert(dobj->objType == DO_FK_CONSTRAINT);
                               7895                 :                : 
                               7896         [ +  + ]:            155 :     for (cell = refidx->partattaches.head; cell; cell = cell->next)
                               7897                 :                :     {
                               7898                 :            110 :         IndexAttachInfo *attach = (IndexAttachInfo *) cell->ptr;
                               7899                 :                : 
                               7900                 :            110 :         addObjectDependency(dobj, attach->dobj.dumpId);
                               7901                 :                : 
                               7902         [ +  + ]:            110 :         if (attach->partitionIdx->partattaches.head != NULL)
                               7903                 :             25 :             addConstrChildIdxDeps(dobj, attach->partitionIdx);
                               7904                 :                :     }
                               7905                 :             45 : }
                               7906                 :                : 
                               7907                 :                : /*
                               7908                 :                :  * getDomainConstraints
                               7909                 :                :  *
                               7910                 :                :  * Get info about constraints on a domain.
                               7911                 :                :  */
                               7912                 :                : static void
 4451 rhaas@postgresql.org     7913                 :            134 : getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
                               7914                 :                : {
                               7915                 :                :     int         i;
                               7916                 :                :     ConstraintInfo *constrinfo;
  860 tgl@sss.pgh.pa.us        7917                 :            134 :     PQExpBuffer query = createPQExpBuffer();
                               7918                 :                :     PGresult   *res;
                               7919                 :                :     int         i_tableoid,
                               7920                 :                :                 i_oid,
                               7921                 :                :                 i_conname,
                               7922                 :                :                 i_consrc;
                               7923                 :                :     int         ntups;
                               7924                 :                : 
                               7925         [ +  + ]:            134 :     if (!fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS])
                               7926                 :                :     {
                               7927                 :                :         /* Set up query for constraint-specific details */
                               7928                 :             44 :         appendPQExpBufferStr(query,
                               7929                 :                :                              "PREPARE getDomainConstraints(pg_catalog.oid) AS\n"
                               7930                 :                :                              "SELECT tableoid, oid, conname, "
                               7931                 :                :                              "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
                               7932                 :                :                              "convalidated "
                               7933                 :                :                              "FROM pg_catalog.pg_constraint "
                               7934                 :                :                              "WHERE contypid = $1 AND contype = 'c' "
                               7935                 :                :                              "ORDER BY conname");
                               7936                 :                : 
                               7937                 :             44 :         ExecuteSqlStatement(fout, query->data);
                               7938                 :                : 
                               7939                 :             44 :         fout->is_prepared[PREPQUERY_GETDOMAINCONSTRAINTS] = true;
                               7940                 :                :     }
                               7941                 :                : 
                               7942                 :            134 :     printfPQExpBuffer(query,
                               7943                 :                :                       "EXECUTE getDomainConstraints('%u')",
                               7944                 :                :                       tyinfo->dobj.catId.oid);
                               7945                 :                : 
 4450 rhaas@postgresql.org     7946                 :            134 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               7947                 :                : 
 7435 tgl@sss.pgh.pa.us        7948                 :            134 :     ntups = PQntuples(res);
                               7949                 :                : 
                               7950                 :            134 :     i_tableoid = PQfnumber(res, "tableoid");
                               7951                 :            134 :     i_oid = PQfnumber(res, "oid");
                               7952                 :            134 :     i_conname = PQfnumber(res, "conname");
                               7953                 :            134 :     i_consrc = PQfnumber(res, "consrc");
                               7954                 :                : 
 4524 bruce@momjian.us         7955                 :            134 :     constrinfo = (ConstraintInfo *) pg_malloc(ntups * sizeof(ConstraintInfo));
                               7956                 :                : 
 5226                          7957                 :            134 :     tyinfo->nDomChecks = ntups;
                               7958                 :            134 :     tyinfo->domChecks = constrinfo;
                               7959                 :                : 
 7435 tgl@sss.pgh.pa.us        7960         [ +  + ]:            223 :     for (i = 0; i < ntups; i++)
                               7961                 :                :     {
 4326 bruce@momjian.us         7962                 :             89 :         bool        validated = PQgetvalue(res, i, 4)[0] == 't';
                               7963                 :                : 
 7435 tgl@sss.pgh.pa.us        7964                 :             89 :         constrinfo[i].dobj.objType = DO_CONSTRAINT;
                               7965                 :             89 :         constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               7966                 :             89 :         constrinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               7967                 :             89 :         AssignDumpId(&constrinfo[i].dobj);
 4524 bruce@momjian.us         7968                 :             89 :         constrinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
 5226                          7969                 :             89 :         constrinfo[i].dobj.namespace = tyinfo->dobj.namespace;
 7435 tgl@sss.pgh.pa.us        7970                 :             89 :         constrinfo[i].contable = NULL;
 5226 bruce@momjian.us         7971                 :             89 :         constrinfo[i].condomain = tyinfo;
 7435 tgl@sss.pgh.pa.us        7972                 :             89 :         constrinfo[i].contype = 'c';
 4524 bruce@momjian.us         7973                 :             89 :         constrinfo[i].condef = pg_strdup(PQgetvalue(res, i, i_consrc));
 5697 tgl@sss.pgh.pa.us        7974                 :             89 :         constrinfo[i].confrelid = InvalidOid;
 7435                          7975                 :             89 :         constrinfo[i].conindex = 0;
 5373                          7976                 :             89 :         constrinfo[i].condeferrable = false;
                               7977                 :             89 :         constrinfo[i].condeferred = false;
 5819                          7978                 :             89 :         constrinfo[i].conislocal = true;
                               7979                 :                : 
 4524 alvherre@alvh.no-ip.     7980                 :             89 :         constrinfo[i].separate = !validated;
                               7981                 :                : 
                               7982                 :                :         /*
                               7983                 :                :          * Make the domain depend on the constraint, ensuring it won't be
                               7984                 :                :          * output till any constraint dependencies are OK.  If the constraint
                               7985                 :                :          * has not been validated, it's going to be dumped after the domain
                               7986                 :                :          * anyway, so this doesn't matter.
                               7987                 :                :          */
                               7988         [ +  - ]:             89 :         if (validated)
                               7989                 :             89 :             addObjectDependency(&tyinfo->dobj,
                               7990                 :             89 :                                 constrinfo[i].dobj.dumpId);
                               7991                 :                :     }
                               7992                 :                : 
 7435 tgl@sss.pgh.pa.us        7993                 :            134 :     PQclear(res);
                               7994                 :                : 
                               7995                 :            134 :     destroyPQExpBuffer(query);
                               7996                 :            134 : }
                               7997                 :                : 
                               7998                 :                : /*
                               7999                 :                :  * getRules
                               8000                 :                :  *    get basic information about every rule in the system
                               8001                 :                :  *
                               8002                 :                :  * numRules is set to the number of rules read in
                               8003                 :                :  */
                               8004                 :                : RuleInfo *
 4451 rhaas@postgresql.org     8005                 :            155 : getRules(Archive *fout, int *numRules)
                               8006                 :                : {
                               8007                 :                :     PGresult   *res;
                               8008                 :                :     int         ntups;
                               8009                 :                :     int         i;
 7435 tgl@sss.pgh.pa.us        8010                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               8011                 :                :     RuleInfo   *ruleinfo;
                               8012                 :                :     int         i_tableoid;
                               8013                 :                :     int         i_oid;
                               8014                 :                :     int         i_rulename;
                               8015                 :                :     int         i_ruletable;
                               8016                 :                :     int         i_ev_type;
                               8017                 :                :     int         i_is_instead;
                               8018                 :                :     int         i_ev_enabled;
                               8019                 :                : 
  852                          8020                 :            155 :     appendPQExpBufferStr(query, "SELECT "
                               8021                 :                :                          "tableoid, oid, rulename, "
                               8022                 :                :                          "ev_class AS ruletable, ev_type, is_instead, "
                               8023                 :                :                          "ev_enabled "
                               8024                 :                :                          "FROM pg_rewrite "
                               8025                 :                :                          "ORDER BY oid");
                               8026                 :                : 
 4450 rhaas@postgresql.org     8027                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8028                 :                : 
 7435 tgl@sss.pgh.pa.us        8029                 :            155 :     ntups = PQntuples(res);
                               8030                 :                : 
                               8031                 :            155 :     *numRules = ntups;
                               8032                 :                : 
 4524 bruce@momjian.us         8033                 :            155 :     ruleinfo = (RuleInfo *) pg_malloc(ntups * sizeof(RuleInfo));
                               8034                 :                : 
 7435 tgl@sss.pgh.pa.us        8035                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8036                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8037                 :            155 :     i_rulename = PQfnumber(res, "rulename");
                               8038                 :            155 :     i_ruletable = PQfnumber(res, "ruletable");
                               8039                 :            155 :     i_ev_type = PQfnumber(res, "ev_type");
                               8040                 :            155 :     i_is_instead = PQfnumber(res, "is_instead");
 6236 JanWieck@Yahoo.com       8041                 :            155 :     i_ev_enabled = PQfnumber(res, "ev_enabled");
                               8042                 :                : 
 7435 tgl@sss.pgh.pa.us        8043         [ +  + ]:          23560 :     for (i = 0; i < ntups; i++)
                               8044                 :                :     {
                               8045                 :                :         Oid         ruletableoid;
                               8046                 :                : 
                               8047                 :          23405 :         ruleinfo[i].dobj.objType = DO_RULE;
                               8048                 :          23405 :         ruleinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8049                 :          23405 :         ruleinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8050                 :          23405 :         AssignDumpId(&ruleinfo[i].dobj);
 4524 bruce@momjian.us         8051                 :          23405 :         ruleinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_rulename));
 7435 tgl@sss.pgh.pa.us        8052                 :          23405 :         ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                               8053                 :          23405 :         ruleinfo[i].ruletable = findTableByOid(ruletableoid);
 6971                          8054         [ -  + ]:          23405 :         if (ruleinfo[i].ruletable == NULL)
  737 tgl@sss.pgh.pa.us        8055                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found",
                               8056                 :                :                      ruletableoid, ruleinfo[i].dobj.catId.oid);
 7347 tgl@sss.pgh.pa.us        8057                 :CBC       23405 :         ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
 6618                          8058                 :          23405 :         ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
 7435                          8059                 :          23405 :         ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
                               8060                 :          23405 :         ruleinfo[i].is_instead = *(PQgetvalue(res, i, i_is_instead)) == 't';
 6236 JanWieck@Yahoo.com       8061                 :          23405 :         ruleinfo[i].ev_enabled = *(PQgetvalue(res, i, i_ev_enabled));
 7435 tgl@sss.pgh.pa.us        8062         [ +  - ]:          23405 :         if (ruleinfo[i].ruletable)
                               8063                 :                :         {
                               8064                 :                :             /*
                               8065                 :                :              * If the table is a view or materialized view, force its ON
                               8066                 :                :              * SELECT rule to be sorted before the view itself --- this
                               8067                 :                :              * ensures that any dependencies for the rule affect the table's
                               8068                 :                :              * positioning. Other rules are forced to appear after their
                               8069                 :                :              * table.
                               8070                 :                :              */
 4060 kgrittn@postgresql.o     8071         [ +  + ]:          23405 :             if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
 4039 andrew@dunslane.net      8072         [ +  + ]:            619 :                  ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
 7435 tgl@sss.pgh.pa.us        8073   [ +  +  +  - ]:          23240 :                 ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
                               8074                 :                :             {
                               8075                 :          22900 :                 addObjectDependency(&ruleinfo[i].ruletable->dobj,
                               8076                 :          22900 :                                     ruleinfo[i].dobj.dumpId);
                               8077                 :                :                 /* We'll merge the rule into CREATE VIEW, if possible */
 7061                          8078                 :          22900 :                 ruleinfo[i].separate = false;
                               8079                 :                :             }
                               8080                 :                :             else
                               8081                 :                :             {
 7435                          8082                 :            505 :                 addObjectDependency(&ruleinfo[i].dobj,
                               8083                 :            505 :                                     ruleinfo[i].ruletable->dobj.dumpId);
 7061                          8084                 :            505 :                 ruleinfo[i].separate = true;
                               8085                 :                :             }
                               8086                 :                :         }
                               8087                 :                :         else
 7061 tgl@sss.pgh.pa.us        8088                 :UBC           0 :             ruleinfo[i].separate = true;
                               8089                 :                :     }
                               8090                 :                : 
 7435 tgl@sss.pgh.pa.us        8091                 :CBC         155 :     PQclear(res);
                               8092                 :                : 
                               8093                 :            155 :     destroyPQExpBuffer(query);
                               8094                 :                : 
                               8095                 :            155 :     return ruleinfo;
                               8096                 :                : }
                               8097                 :                : 
                               8098                 :                : /*
                               8099                 :                :  * getTriggers
                               8100                 :                :  *    get information about every trigger on a dumpable table
                               8101                 :                :  *
                               8102                 :                :  * Note: trigger data is not returned directly to the caller, but it
                               8103                 :                :  * does get entered into the DumpableObject tables.
                               8104                 :                :  */
                               8105                 :                : void
 4451 rhaas@postgresql.org     8106                 :            155 : getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
                               8107                 :                : {
 7435 tgl@sss.pgh.pa.us        8108                 :            155 :     PQExpBuffer query = createPQExpBuffer();
  860                          8109                 :            155 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8110                 :                :     PGresult   *res;
                               8111                 :                :     int         ntups;
                               8112                 :                :     int         curtblindx;
                               8113                 :                :     TriggerInfo *tginfo;
                               8114                 :                :     int         i_tableoid,
                               8115                 :                :                 i_oid,
                               8116                 :                :                 i_tgrelid,
                               8117                 :                :                 i_tgname,
                               8118                 :                :                 i_tgenabled,
                               8119                 :                :                 i_tgispartition,
                               8120                 :                :                 i_tgdef;
                               8121                 :                : 
                               8122                 :                :     /*
                               8123                 :                :      * We want to perform just one query against pg_trigger.  However, we
                               8124                 :                :      * mustn't try to select every row of the catalog and then sort it out on
                               8125                 :                :      * the client side, because some of the server-side functions we need
                               8126                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8127                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8128                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8129                 :                :      */
                               8130                 :            155 :     appendPQExpBufferChar(tbloids, '{');
                               8131         [ +  + ]:          39419 :     for (int i = 0; i < numTables; i++)
                               8132                 :                :     {
 7435                          8133                 :          39264 :         TableInfo  *tbinfo = &tblinfo[i];
                               8134                 :                : 
 2930 sfrost@snowman.net       8135         [ +  + ]:          39264 :         if (!tbinfo->hastriggers ||
                               8136         [ +  + ]:            916 :             !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
 7435 tgl@sss.pgh.pa.us        8137                 :          38406 :             continue;
                               8138                 :                : 
                               8139                 :                :         /* OK, we need info for this table */
  860                          8140         [ +  + ]:            858 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8141                 :            806 :             appendPQExpBufferChar(tbloids, ',');
                               8142                 :            858 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               8143                 :                :     }
                               8144                 :            155 :     appendPQExpBufferChar(tbloids, '}');
                               8145                 :                : 
  830 alvherre@alvh.no-ip.     8146         [ +  - ]:            155 :     if (fout->remoteVersion >= 150000)
                               8147                 :                :     {
                               8148                 :                :         /*
                               8149                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8150                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8151                 :                :          * under-parenthesization.
                               8152                 :                :          *
                               8153                 :                :          * NB: We need to see partition triggers in case the tgenabled flag
                               8154                 :                :          * has been changed from the parent.
                               8155                 :                :          */
                               8156                 :            155 :         appendPQExpBuffer(query,
                               8157                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8158                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8159                 :                :                           "t.tgenabled, t.tableoid, t.oid, "
                               8160                 :                :                           "t.tgparentid <> 0 AS tgispartition\n"
                               8161                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8162                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8163                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8164                 :                :                           "WHERE ((NOT t.tgisinternal AND t.tgparentid = 0) "
                               8165                 :                :                           "OR t.tgenabled != u.tgenabled) "
                               8166                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8167                 :                :                           tbloids->data);
                               8168                 :                :     }
  830 alvherre@alvh.no-ip.     8169         [ #  # ]:UBC           0 :     else if (fout->remoteVersion >= 130000)
                               8170                 :                :     {
                               8171                 :                :         /*
                               8172                 :                :          * NB: think not to use pretty=true in pg_get_triggerdef.  It could
                               8173                 :                :          * result in non-forward-compatible dumps of WHEN clauses due to
                               8174                 :                :          * under-parenthesization.
                               8175                 :                :          *
                               8176                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8177                 :                :          * tgenabled flag has been changed from the parent.
                               8178                 :                :          */
  860 tgl@sss.pgh.pa.us        8179                 :              0 :         appendPQExpBuffer(query,
                               8180                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8181                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8182                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition\n"
                               8183                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8184                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8185                 :                :                           "LEFT JOIN pg_catalog.pg_trigger u ON (u.oid = t.tgparentid) "
                               8186                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != u.tgenabled) "
                               8187                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8188                 :                :                           tbloids->data);
                               8189                 :                :     }
                               8190         [ #  # ]:              0 :     else if (fout->remoteVersion >= 110000)
                               8191                 :                :     {
                               8192                 :                :         /*
                               8193                 :                :          * NB: We need to see tgisinternal triggers in partitions, in case the
                               8194                 :                :          * tgenabled flag has been changed from the parent. No tgparentid in
                               8195                 :                :          * version 11-12, so we have to match them via pg_depend.
                               8196                 :                :          *
                               8197                 :                :          * See above about pretty=true in pg_get_triggerdef.
                               8198                 :                :          */
                               8199                 :              0 :         appendPQExpBuffer(query,
                               8200                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8201                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8202                 :                :                           "t.tgenabled, t.tableoid, t.oid, t.tgisinternal as tgispartition "
                               8203                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8204                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8205                 :                :                           "LEFT JOIN pg_catalog.pg_depend AS d ON "
                               8206                 :                :                           " d.classid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8207                 :                :                           " d.refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass AND "
                               8208                 :                :                           " d.objid = t.oid "
                               8209                 :                :                           "LEFT JOIN pg_catalog.pg_trigger AS pt ON pt.oid = refobjid "
                               8210                 :                :                           "WHERE (NOT t.tgisinternal OR t.tgenabled != pt.tgenabled) "
                               8211                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8212                 :                :                           tbloids->data);
                               8213                 :                :     }
                               8214                 :                :     else
                               8215                 :                :     {
                               8216                 :                :         /* See above about pretty=true in pg_get_triggerdef */
                               8217                 :              0 :         appendPQExpBuffer(query,
                               8218                 :                :                           "SELECT t.tgrelid, t.tgname, "
                               8219                 :                :                           "pg_catalog.pg_get_triggerdef(t.oid, false) AS tgdef, "
                               8220                 :                :                           "t.tgenabled, false as tgispartition, "
                               8221                 :                :                           "t.tableoid, t.oid "
                               8222                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8223                 :                :                           "JOIN pg_catalog.pg_trigger t ON (src.tbloid = t.tgrelid) "
                               8224                 :                :                           "WHERE NOT tgisinternal "
                               8225                 :                :                           "ORDER BY t.tgrelid, t.tgname",
                               8226                 :                :                           tbloids->data);
                               8227                 :                :     }
                               8228                 :                : 
  860 tgl@sss.pgh.pa.us        8229                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8230                 :                : 
                               8231                 :            155 :     ntups = PQntuples(res);
                               8232                 :                : 
                               8233                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8234                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8235                 :            155 :     i_tgrelid = PQfnumber(res, "tgrelid");
                               8236                 :            155 :     i_tgname = PQfnumber(res, "tgname");
                               8237                 :            155 :     i_tgenabled = PQfnumber(res, "tgenabled");
  830 alvherre@alvh.no-ip.     8238                 :            155 :     i_tgispartition = PQfnumber(res, "tgispartition");
  860 tgl@sss.pgh.pa.us        8239                 :            155 :     i_tgdef = PQfnumber(res, "tgdef");
                               8240                 :                : 
                               8241                 :            155 :     tginfo = (TriggerInfo *) pg_malloc(ntups * sizeof(TriggerInfo));
                               8242                 :                : 
                               8243                 :                :     /*
                               8244                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               8245                 :                :      * j is handled by the inner loop.
                               8246                 :                :      */
                               8247                 :            155 :     curtblindx = -1;
                               8248         [ +  + ]:            461 :     for (int j = 0; j < ntups;)
                               8249                 :                :     {
                               8250                 :            306 :         Oid         tgrelid = atooid(PQgetvalue(res, j, i_tgrelid));
                               8251                 :            306 :         TableInfo  *tbinfo = NULL;
                               8252                 :                :         int         numtrigs;
                               8253                 :                : 
                               8254                 :                :         /* Count rows for this table */
                               8255         [ +  + ]:            508 :         for (numtrigs = 1; numtrigs < ntups - j; numtrigs++)
                               8256         [ +  + ]:            456 :             if (atooid(PQgetvalue(res, j + numtrigs, i_tgrelid)) != tgrelid)
                               8257                 :            254 :                 break;
                               8258                 :                : 
                               8259                 :                :         /*
                               8260                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8261                 :                :          * order.
                               8262                 :                :          */
                               8263         [ +  - ]:          15799 :         while (++curtblindx < numTables)
                               8264                 :                :         {
                               8265                 :          15799 :             tbinfo = &tblinfo[curtblindx];
                               8266         [ +  + ]:          15799 :             if (tbinfo->dobj.catId.oid == tgrelid)
                               8267                 :            306 :                 break;
                               8268                 :                :         }
                               8269         [ -  + ]:            306 :         if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        8270                 :UBC           0 :             pg_fatal("unrecognized table OID %u", tgrelid);
                               8271                 :                : 
                               8272                 :                :         /* Save data for this table */
  860 tgl@sss.pgh.pa.us        8273                 :CBC         306 :         tbinfo->triggers = tginfo + j;
                               8274                 :            306 :         tbinfo->numTriggers = numtrigs;
                               8275                 :                : 
                               8276         [ +  + ]:            814 :         for (int c = 0; c < numtrigs; c++, j++)
                               8277                 :                :         {
 7435                          8278                 :            508 :             tginfo[j].dobj.objType = DO_TRIGGER;
                               8279                 :            508 :             tginfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               8280                 :            508 :             tginfo[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
                               8281                 :            508 :             AssignDumpId(&tginfo[j].dobj);
 4524 bruce@momjian.us         8282                 :            508 :             tginfo[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_tgname));
 7347 tgl@sss.pgh.pa.us        8283                 :            508 :             tginfo[j].dobj.namespace = tbinfo->dobj.namespace;
 7435                          8284                 :            508 :             tginfo[j].tgtable = tbinfo;
 6236 JanWieck@Yahoo.com       8285                 :            508 :             tginfo[j].tgenabled = *(PQgetvalue(res, j, i_tgenabled));
  830 alvherre@alvh.no-ip.     8286                 :            508 :             tginfo[j].tgispartition = *(PQgetvalue(res, j, i_tgispartition)) == 't';
   91 peter@eisentraut.org     8287                 :GNC         508 :             tginfo[j].tgdef = pg_strdup(PQgetvalue(res, j, i_tgdef));
                               8288                 :                :         }
                               8289                 :                :     }
                               8290                 :                : 
  860 tgl@sss.pgh.pa.us        8291                 :CBC         155 :     PQclear(res);
                               8292                 :                : 
 7435                          8293                 :            155 :     destroyPQExpBuffer(query);
  860                          8294                 :            155 :     destroyPQExpBuffer(tbloids);
 7435                          8295                 :            155 : }
                               8296                 :                : 
                               8297                 :                : /*
                               8298                 :                :  * getEventTriggers
                               8299                 :                :  *    get information about event triggers
                               8300                 :                :  */
                               8301                 :                : EventTriggerInfo *
 4288 rhaas@postgresql.org     8302                 :            155 : getEventTriggers(Archive *fout, int *numEventTriggers)
                               8303                 :                : {
                               8304                 :                :     int         i;
                               8305                 :                :     PQExpBuffer query;
                               8306                 :                :     PGresult   *res;
                               8307                 :                :     EventTriggerInfo *evtinfo;
                               8308                 :                :     int         i_tableoid,
                               8309                 :                :                 i_oid,
                               8310                 :                :                 i_evtname,
                               8311                 :                :                 i_evtevent,
                               8312                 :                :                 i_evtowner,
                               8313                 :                :                 i_evttags,
                               8314                 :                :                 i_evtfname,
                               8315                 :                :                 i_evtenabled;
                               8316                 :                :     int         ntups;
                               8317                 :                : 
                               8318                 :                :     /* Before 9.3, there are no event triggers */
                               8319         [ -  + ]:            155 :     if (fout->remoteVersion < 90300)
                               8320                 :                :     {
 4288 rhaas@postgresql.org     8321                 :UBC           0 :         *numEventTriggers = 0;
                               8322                 :              0 :         return NULL;
                               8323                 :                :     }
                               8324                 :                : 
 3927 sfrost@snowman.net       8325                 :CBC         155 :     query = createPQExpBuffer();
                               8326                 :                : 
  586 drowley@postgresql.o     8327                 :            155 :     appendPQExpBufferStr(query,
                               8328                 :                :                          "SELECT e.tableoid, e.oid, evtname, evtenabled, "
                               8329                 :                :                          "evtevent, evtowner, "
                               8330                 :                :                          "array_to_string(array("
                               8331                 :                :                          "select quote_literal(x) "
                               8332                 :                :                          " from unnest(evttags) as t(x)), ', ') as evttags, "
                               8333                 :                :                          "e.evtfoid::regproc as evtfname "
                               8334                 :                :                          "FROM pg_event_trigger e "
                               8335                 :                :                          "ORDER BY e.oid");
                               8336                 :                : 
 4288 rhaas@postgresql.org     8337                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8338                 :                : 
                               8339                 :            155 :     ntups = PQntuples(res);
                               8340                 :                : 
                               8341                 :            155 :     *numEventTriggers = ntups;
                               8342                 :                : 
                               8343                 :            155 :     evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
                               8344                 :                : 
                               8345                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8346                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8347                 :            155 :     i_evtname = PQfnumber(res, "evtname");
                               8348                 :            155 :     i_evtevent = PQfnumber(res, "evtevent");
                               8349                 :            155 :     i_evtowner = PQfnumber(res, "evtowner");
                               8350                 :            155 :     i_evttags = PQfnumber(res, "evttags");
                               8351                 :            155 :     i_evtfname = PQfnumber(res, "evtfname");
                               8352                 :            155 :     i_evtenabled = PQfnumber(res, "evtenabled");
                               8353                 :                : 
                               8354         [ +  + ]:            206 :     for (i = 0; i < ntups; i++)
                               8355                 :                :     {
                               8356                 :             51 :         evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
                               8357                 :             51 :         evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8358                 :             51 :         evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8359                 :             51 :         AssignDumpId(&evtinfo[i].dobj);
                               8360                 :             51 :         evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8361                 :             51 :         evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
                               8362                 :             51 :         evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
  835 tgl@sss.pgh.pa.us        8363                 :             51 :         evtinfo[i].evtowner = getRoleName(PQgetvalue(res, i, i_evtowner));
 4288 rhaas@postgresql.org     8364                 :             51 :         evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
                               8365                 :             51 :         evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
                               8366                 :             51 :         evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
                               8367                 :                : 
                               8368                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       8369                 :             51 :         selectDumpableObject(&(evtinfo[i].dobj), fout);
                               8370                 :                :     }
                               8371                 :                : 
 4288 rhaas@postgresql.org     8372                 :            155 :     PQclear(res);
                               8373                 :                : 
                               8374                 :            155 :     destroyPQExpBuffer(query);
                               8375                 :                : 
                               8376                 :            155 :     return evtinfo;
                               8377                 :                : }
                               8378                 :                : 
                               8379                 :                : /*
                               8380                 :                :  * getProcLangs
                               8381                 :                :  *    get basic information about every procedural language in the system
                               8382                 :                :  *
                               8383                 :                :  * numProcLangs is set to the number of langs read in
                               8384                 :                :  *
                               8385                 :                :  * NB: this must run after getFuncs() because we assume we can do
                               8386                 :                :  * findFuncByOid().
                               8387                 :                :  */
                               8388                 :                : ProcLangInfo *
 4451                          8389                 :            155 : getProcLangs(Archive *fout, int *numProcLangs)
                               8390                 :                : {
                               8391                 :                :     PGresult   *res;
                               8392                 :                :     int         ntups;
                               8393                 :                :     int         i;
 7435 tgl@sss.pgh.pa.us        8394                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               8395                 :                :     ProcLangInfo *planginfo;
                               8396                 :                :     int         i_tableoid;
                               8397                 :                :     int         i_oid;
                               8398                 :                :     int         i_lanname;
                               8399                 :                :     int         i_lanpltrusted;
                               8400                 :                :     int         i_lanplcallfoid;
                               8401                 :                :     int         i_laninline;
                               8402                 :                :     int         i_lanvalidator;
                               8403                 :                :     int         i_lanacl;
                               8404                 :                :     int         i_acldefault;
                               8405                 :                :     int         i_lanowner;
                               8406                 :                : 
  586 drowley@postgresql.o     8407                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8408                 :                :                          "lanname, lanpltrusted, lanplcallfoid, "
                               8409                 :                :                          "laninline, lanvalidator, "
                               8410                 :                :                          "lanacl, "
                               8411                 :                :                          "acldefault('l', lanowner) AS acldefault, "
                               8412                 :                :                          "lanowner "
                               8413                 :                :                          "FROM pg_language "
                               8414                 :                :                          "WHERE lanispl "
                               8415                 :                :                          "ORDER BY oid");
                               8416                 :                : 
 4450 rhaas@postgresql.org     8417                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8418                 :                : 
 7435 tgl@sss.pgh.pa.us        8419                 :            155 :     ntups = PQntuples(res);
                               8420                 :                : 
                               8421                 :            155 :     *numProcLangs = ntups;
                               8422                 :                : 
 4524 bruce@momjian.us         8423                 :            155 :     planginfo = (ProcLangInfo *) pg_malloc(ntups * sizeof(ProcLangInfo));
                               8424                 :                : 
 7435 tgl@sss.pgh.pa.us        8425                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8426                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8427                 :            155 :     i_lanname = PQfnumber(res, "lanname");
                               8428                 :            155 :     i_lanpltrusted = PQfnumber(res, "lanpltrusted");
                               8429                 :            155 :     i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
 5318                          8430                 :            155 :     i_laninline = PQfnumber(res, "laninline");
 6707                          8431                 :            155 :     i_lanvalidator = PQfnumber(res, "lanvalidator");
                               8432                 :            155 :     i_lanacl = PQfnumber(res, "lanacl");
  860                          8433                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
 6707                          8434                 :            155 :     i_lanowner = PQfnumber(res, "lanowner");
                               8435                 :                : 
 7435                          8436         [ +  + ]:            356 :     for (i = 0; i < ntups; i++)
                               8437                 :                :     {
                               8438                 :            201 :         planginfo[i].dobj.objType = DO_PROCLANG;
                               8439                 :            201 :         planginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8440                 :            201 :         planginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8441                 :            201 :         AssignDumpId(&planginfo[i].dobj);
                               8442                 :                : 
 4524 bruce@momjian.us         8443                 :            201 :         planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
  860 tgl@sss.pgh.pa.us        8444                 :            201 :         planginfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_lanacl));
                               8445                 :            201 :         planginfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               8446                 :            201 :         planginfo[i].dacl.privtype = 0;
                               8447                 :            201 :         planginfo[i].dacl.initprivs = NULL;
 7435                          8448                 :            201 :         planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
                               8449                 :            201 :         planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
 3170                          8450                 :            201 :         planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
                               8451                 :            201 :         planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
  835                          8452                 :            201 :         planginfo[i].lanowner = getRoleName(PQgetvalue(res, i, i_lanowner));
                               8453                 :                : 
                               8454                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       8455                 :            201 :         selectDumpableProcLang(&(planginfo[i]), fout);
                               8456                 :                : 
                               8457                 :                :         /* Mark whether language has an ACL */
  860 tgl@sss.pgh.pa.us        8458         [ +  + ]:            201 :         if (!PQgetisnull(res, i, i_lanacl))
                               8459                 :             46 :             planginfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               8460                 :                :     }
                               8461                 :                : 
 7435                          8462                 :            155 :     PQclear(res);
                               8463                 :                : 
                               8464                 :            155 :     destroyPQExpBuffer(query);
                               8465                 :                : 
                               8466                 :            155 :     return planginfo;
                               8467                 :                : }
                               8468                 :                : 
                               8469                 :                : /*
                               8470                 :                :  * getCasts
                               8471                 :                :  *    get basic information about most casts in the system
                               8472                 :                :  *
                               8473                 :                :  * numCasts is set to the number of casts read in
                               8474                 :                :  *
                               8475                 :                :  * Skip casts from a range to its multirange, since we'll create those
                               8476                 :                :  * automatically.
                               8477                 :                :  */
                               8478                 :                : CastInfo *
 3014                          8479                 :            155 : getCasts(Archive *fout, int *numCasts)
                               8480                 :                : {
                               8481                 :                :     PGresult   *res;
                               8482                 :                :     int         ntups;
                               8483                 :                :     int         i;
 7435                          8484                 :            155 :     PQExpBuffer query = createPQExpBuffer();
                               8485                 :                :     CastInfo   *castinfo;
                               8486                 :                :     int         i_tableoid;
                               8487                 :                :     int         i_oid;
                               8488                 :                :     int         i_castsource;
                               8489                 :                :     int         i_casttarget;
                               8490                 :                :     int         i_castfunc;
                               8491                 :                :     int         i_castcontext;
                               8492                 :                :     int         i_castmethod;
                               8493                 :                : 
 1211 akorotkov@postgresql     8494         [ +  - ]:            155 :     if (fout->remoteVersion >= 140000)
                               8495                 :                :     {
                               8496                 :            155 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8497                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               8498                 :                :                              "castmethod "
                               8499                 :                :                              "FROM pg_cast c "
                               8500                 :                :                              "WHERE NOT EXISTS ( "
                               8501                 :                :                              "SELECT 1 FROM pg_range r "
                               8502                 :                :                              "WHERE c.castsource = r.rngtypid "
                               8503                 :                :                              "AND c.casttarget = r.rngmultitypid "
                               8504                 :                :                              ") "
                               8505                 :                :                              "ORDER BY 3,4");
                               8506                 :                :     }
                               8507                 :                :     else
                               8508                 :                :     {
 3800 heikki.linnakangas@i     8509                 :UBC           0 :         appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8510                 :                :                              "castsource, casttarget, castfunc, castcontext, "
                               8511                 :                :                              "castmethod "
                               8512                 :                :                              "FROM pg_cast ORDER BY 3,4");
                               8513                 :                :     }
                               8514                 :                : 
 4450 rhaas@postgresql.org     8515                 :CBC         155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8516                 :                : 
 7435 tgl@sss.pgh.pa.us        8517                 :            155 :     ntups = PQntuples(res);
                               8518                 :                : 
                               8519                 :            155 :     *numCasts = ntups;
                               8520                 :                : 
 4524 bruce@momjian.us         8521                 :            155 :     castinfo = (CastInfo *) pg_malloc(ntups * sizeof(CastInfo));
                               8522                 :                : 
 7435 tgl@sss.pgh.pa.us        8523                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8524                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8525                 :            155 :     i_castsource = PQfnumber(res, "castsource");
                               8526                 :            155 :     i_casttarget = PQfnumber(res, "casttarget");
                               8527                 :            155 :     i_castfunc = PQfnumber(res, "castfunc");
                               8528                 :            155 :     i_castcontext = PQfnumber(res, "castcontext");
 5644 heikki.linnakangas@i     8529                 :            155 :     i_castmethod = PQfnumber(res, "castmethod");
                               8530                 :                : 
 7435 tgl@sss.pgh.pa.us        8531         [ +  + ]:          34796 :     for (i = 0; i < ntups; i++)
                               8532                 :                :     {
                               8533                 :                :         PQExpBufferData namebuf;
                               8534                 :                :         TypeInfo   *sTypeInfo;
                               8535                 :                :         TypeInfo   *tTypeInfo;
                               8536                 :                : 
                               8537                 :          34641 :         castinfo[i].dobj.objType = DO_CAST;
                               8538                 :          34641 :         castinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8539                 :          34641 :         castinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8540                 :          34641 :         AssignDumpId(&castinfo[i].dobj);
                               8541                 :          34641 :         castinfo[i].castsource = atooid(PQgetvalue(res, i, i_castsource));
                               8542                 :          34641 :         castinfo[i].casttarget = atooid(PQgetvalue(res, i, i_casttarget));
                               8543                 :          34641 :         castinfo[i].castfunc = atooid(PQgetvalue(res, i, i_castfunc));
                               8544                 :          34641 :         castinfo[i].castcontext = *(PQgetvalue(res, i, i_castcontext));
 5644 heikki.linnakangas@i     8545                 :          34641 :         castinfo[i].castmethod = *(PQgetvalue(res, i, i_castmethod));
                               8546                 :                : 
                               8547                 :                :         /*
                               8548                 :                :          * Try to name cast as concatenation of typnames.  This is only used
                               8549                 :                :          * for purposes of sorting.  If we fail to find either type, the name
                               8550                 :                :          * will be an empty string.
                               8551                 :                :          */
 7347 tgl@sss.pgh.pa.us        8552                 :          34641 :         initPQExpBuffer(&namebuf);
                               8553                 :          34641 :         sTypeInfo = findTypeByOid(castinfo[i].castsource);
                               8554                 :          34641 :         tTypeInfo = findTypeByOid(castinfo[i].casttarget);
                               8555   [ +  -  +  - ]:          34641 :         if (sTypeInfo && tTypeInfo)
                               8556                 :          34641 :             appendPQExpBuffer(&namebuf, "%s %s",
                               8557                 :                :                               sTypeInfo->dobj.name, tTypeInfo->dobj.name);
                               8558                 :          34641 :         castinfo[i].dobj.name = namebuf.data;
                               8559                 :                : 
                               8560                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       8561                 :          34641 :         selectDumpableCast(&(castinfo[i]), fout);
                               8562                 :                :     }
                               8563                 :                : 
 7435 tgl@sss.pgh.pa.us        8564                 :            155 :     PQclear(res);
                               8565                 :                : 
                               8566                 :            155 :     destroyPQExpBuffer(query);
                               8567                 :                : 
                               8568                 :            155 :     return castinfo;
                               8569                 :                : }
                               8570                 :                : 
                               8571                 :                : static char *
 3276 peter_e@gmx.net          8572                 :             91 : get_language_name(Archive *fout, Oid langid)
                               8573                 :                : {
                               8574                 :                :     PQExpBuffer query;
                               8575                 :                :     PGresult   *res;
                               8576                 :                :     char       *lanname;
                               8577                 :                : 
                               8578                 :             91 :     query = createPQExpBuffer();
                               8579                 :             91 :     appendPQExpBuffer(query, "SELECT lanname FROM pg_language WHERE oid = %u", langid);
                               8580                 :             91 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                               8581                 :             91 :     lanname = pg_strdup(fmtId(PQgetvalue(res, 0, 0)));
                               8582                 :             91 :     destroyPQExpBuffer(query);
                               8583                 :             91 :     PQclear(res);
                               8584                 :                : 
                               8585                 :             91 :     return lanname;
                               8586                 :                : }
                               8587                 :                : 
                               8588                 :                : /*
                               8589                 :                :  * getTransforms
                               8590                 :                :  *    get basic information about every transform in the system
                               8591                 :                :  *
                               8592                 :                :  * numTransforms is set to the number of transforms read in
                               8593                 :                :  */
                               8594                 :                : TransformInfo *
                               8595                 :            155 : getTransforms(Archive *fout, int *numTransforms)
                               8596                 :                : {
                               8597                 :                :     PGresult   *res;
                               8598                 :                :     int         ntups;
                               8599                 :                :     int         i;
                               8600                 :                :     PQExpBuffer query;
                               8601                 :                :     TransformInfo *transforminfo;
                               8602                 :                :     int         i_tableoid;
                               8603                 :                :     int         i_oid;
                               8604                 :                :     int         i_trftype;
                               8605                 :                :     int         i_trflang;
                               8606                 :                :     int         i_trffromsql;
                               8607                 :                :     int         i_trftosql;
                               8608                 :                : 
                               8609                 :                :     /* Transforms didn't exist pre-9.5 */
                               8610         [ -  + ]:            155 :     if (fout->remoteVersion < 90500)
                               8611                 :                :     {
 3276 peter_e@gmx.net          8612                 :UBC           0 :         *numTransforms = 0;
                               8613                 :              0 :         return NULL;
                               8614                 :                :     }
                               8615                 :                : 
 3265 magnus@hagander.net      8616                 :CBC         155 :     query = createPQExpBuffer();
                               8617                 :                : 
 1746 drowley@postgresql.o     8618                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, "
                               8619                 :                :                          "trftype, trflang, trffromsql::oid, trftosql::oid "
                               8620                 :                :                          "FROM pg_transform "
                               8621                 :                :                          "ORDER BY 3,4");
                               8622                 :                : 
 3276 peter_e@gmx.net          8623                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               8624                 :                : 
                               8625                 :            155 :     ntups = PQntuples(res);
                               8626                 :                : 
                               8627                 :            155 :     *numTransforms = ntups;
                               8628                 :                : 
                               8629                 :            155 :     transforminfo = (TransformInfo *) pg_malloc(ntups * sizeof(TransformInfo));
                               8630                 :                : 
                               8631                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               8632                 :            155 :     i_oid = PQfnumber(res, "oid");
                               8633                 :            155 :     i_trftype = PQfnumber(res, "trftype");
                               8634                 :            155 :     i_trflang = PQfnumber(res, "trflang");
                               8635                 :            155 :     i_trffromsql = PQfnumber(res, "trffromsql");
                               8636                 :            155 :     i_trftosql = PQfnumber(res, "trftosql");
                               8637                 :                : 
                               8638         [ +  + ]:            206 :     for (i = 0; i < ntups; i++)
                               8639                 :                :     {
                               8640                 :                :         PQExpBufferData namebuf;
                               8641                 :                :         TypeInfo   *typeInfo;
                               8642                 :                :         char       *lanname;
                               8643                 :                : 
                               8644                 :             51 :         transforminfo[i].dobj.objType = DO_TRANSFORM;
                               8645                 :             51 :         transforminfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               8646                 :             51 :         transforminfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               8647                 :             51 :         AssignDumpId(&transforminfo[i].dobj);
                               8648                 :             51 :         transforminfo[i].trftype = atooid(PQgetvalue(res, i, i_trftype));
                               8649                 :             51 :         transforminfo[i].trflang = atooid(PQgetvalue(res, i, i_trflang));
                               8650                 :             51 :         transforminfo[i].trffromsql = atooid(PQgetvalue(res, i, i_trffromsql));
                               8651                 :             51 :         transforminfo[i].trftosql = atooid(PQgetvalue(res, i, i_trftosql));
                               8652                 :                : 
                               8653                 :                :         /*
                               8654                 :                :          * Try to name transform as concatenation of type and language name.
                               8655                 :                :          * This is only used for purposes of sorting.  If we fail to find
                               8656                 :                :          * either, the name will be an empty string.
                               8657                 :                :          */
                               8658                 :             51 :         initPQExpBuffer(&namebuf);
                               8659                 :             51 :         typeInfo = findTypeByOid(transforminfo[i].trftype);
                               8660                 :             51 :         lanname = get_language_name(fout, transforminfo[i].trflang);
                               8661   [ +  -  +  - ]:             51 :         if (typeInfo && lanname)
                               8662                 :             51 :             appendPQExpBuffer(&namebuf, "%s %s",
                               8663                 :                :                               typeInfo->dobj.name, lanname);
                               8664                 :             51 :         transforminfo[i].dobj.name = namebuf.data;
 3199 tgl@sss.pgh.pa.us        8665                 :             51 :         free(lanname);
                               8666                 :                : 
                               8667                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       8668                 :             51 :         selectDumpableObject(&(transforminfo[i].dobj), fout);
                               8669                 :                :     }
                               8670                 :                : 
 3276 peter_e@gmx.net          8671                 :            155 :     PQclear(res);
                               8672                 :                : 
                               8673                 :            155 :     destroyPQExpBuffer(query);
                               8674                 :                : 
                               8675                 :            155 :     return transforminfo;
                               8676                 :                : }
                               8677                 :                : 
                               8678                 :                : /*
                               8679                 :                :  * getTableAttrs -
                               8680                 :                :  *    for each interesting table, read info about its attributes
                               8681                 :                :  *    (names, types, default values, CHECK constraints, etc)
                               8682                 :                :  *
                               8683                 :                :  *  modifies tblinfo
                               8684                 :                :  */
                               8685                 :                : void
 3014 tgl@sss.pgh.pa.us        8686                 :            155 : getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
                               8687                 :                : {
                               8688                 :            155 :     DumpOptions *dopt = fout->dopt;
 7435                          8689                 :            155 :     PQExpBuffer q = createPQExpBuffer();
  860                          8690                 :            155 :     PQExpBuffer tbloids = createPQExpBuffer();
                               8691                 :            155 :     PQExpBuffer checkoids = createPQExpBuffer();
                               8692                 :                :     PGresult   *res;
                               8693                 :                :     int         ntups;
                               8694                 :                :     int         curtblindx;
                               8695                 :                :     int         i_attrelid;
                               8696                 :                :     int         i_attnum;
                               8697                 :                :     int         i_attname;
                               8698                 :                :     int         i_atttypname;
                               8699                 :                :     int         i_attstattarget;
                               8700                 :                :     int         i_attstorage;
                               8701                 :                :     int         i_typstorage;
                               8702                 :                :     int         i_attidentity;
                               8703                 :                :     int         i_attgenerated;
                               8704                 :                :     int         i_attisdropped;
                               8705                 :                :     int         i_attlen;
                               8706                 :                :     int         i_attalign;
                               8707                 :                :     int         i_attislocal;
                               8708                 :                :     int         i_notnull_name;
                               8709                 :                :     int         i_notnull_noinherit;
                               8710                 :                :     int         i_notnull_is_pk;
                               8711                 :                :     int         i_notnull_inh;
                               8712                 :                :     int         i_attoptions;
                               8713                 :                :     int         i_attcollation;
                               8714                 :                :     int         i_attcompression;
                               8715                 :                :     int         i_attfdwoptions;
                               8716                 :                :     int         i_attmissingval;
                               8717                 :                :     int         i_atthasdef;
                               8718                 :                : 
                               8719                 :                :     /*
                               8720                 :                :      * We want to perform just one query against pg_attribute, and then just
                               8721                 :                :      * one against pg_attrdef (for DEFAULTs) and two against pg_constraint
                               8722                 :                :      * (for CHECK constraints and for NOT NULL constraints).  However, we
                               8723                 :                :      * mustn't try to select every row of those catalogs and then sort it out
                               8724                 :                :      * on the client side, because some of the server-side functions we need
                               8725                 :                :      * would be unsafe to apply to tables we don't have lock on.  Hence, we
                               8726                 :                :      * build an array of the OIDs of tables we care about (and now have lock
                               8727                 :                :      * on!), and use a WHERE clause to constrain which rows are selected.
                               8728                 :                :      */
                               8729                 :            155 :     appendPQExpBufferChar(tbloids, '{');
                               8730                 :            155 :     appendPQExpBufferChar(checkoids, '{');
 1375 peter@eisentraut.org     8731         [ +  + ]:          39419 :     for (int i = 0; i < numTables; i++)
                               8732                 :                :     {
 7893 bruce@momjian.us         8733                 :          39264 :         TableInfo  *tbinfo = &tblinfo[i];
                               8734                 :                : 
                               8735                 :                :         /* Don't bother to collect info for sequences */
 7909 tgl@sss.pgh.pa.us        8736         [ +  + ]:          39264 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
 9716 bruce@momjian.us         8737                 :            515 :             continue;
                               8738                 :                : 
                               8739                 :                :         /* Don't bother with uninteresting tables, either */
 7909 tgl@sss.pgh.pa.us        8740         [ +  + ]:          38749 :         if (!tbinfo->interesting)
 8010                          8741                 :          33168 :             continue;
                               8742                 :                : 
                               8743                 :                :         /* OK, we need info for this table */
  860                          8744         [ +  + ]:           5581 :         if (tbloids->len > 1) /* do we have more than the '{'? */
                               8745                 :           5478 :             appendPQExpBufferChar(tbloids, ',');
                               8746                 :           5581 :         appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               8747                 :                : 
                               8748         [ +  + ]:           5581 :         if (tbinfo->ncheck > 0)
                               8749                 :                :         {
                               8750                 :                :             /* Also make a list of the ones with check constraints */
                               8751         [ +  + ]:            466 :             if (checkoids->len > 1) /* do we have more than the '{'? */
                               8752                 :            397 :                 appendPQExpBufferChar(checkoids, ',');
                               8753                 :            466 :             appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid);
                               8754                 :                :         }
                               8755                 :                :     }
                               8756                 :            155 :     appendPQExpBufferChar(tbloids, '}');
                               8757                 :            155 :     appendPQExpBufferChar(checkoids, '}');
                               8758                 :                : 
                               8759                 :                :     /*
                               8760                 :                :      * Find all the user attributes and their types.
                               8761                 :                :      *
                               8762                 :                :      * Since we only want to dump COLLATE clauses for attributes whose
                               8763                 :                :      * collation is different from their type's default, we use a CASE here to
                               8764                 :                :      * suppress uninteresting attcollations cheaply.
                               8765                 :                :      */
                               8766                 :            155 :     appendPQExpBufferStr(q,
                               8767                 :                :                          "SELECT\n"
                               8768                 :                :                          "a.attrelid,\n"
                               8769                 :                :                          "a.attnum,\n"
                               8770                 :                :                          "a.attname,\n"
                               8771                 :                :                          "a.attstattarget,\n"
                               8772                 :                :                          "a.attstorage,\n"
                               8773                 :                :                          "t.typstorage,\n"
                               8774                 :                :                          "a.atthasdef,\n"
                               8775                 :                :                          "a.attisdropped,\n"
                               8776                 :                :                          "a.attlen,\n"
                               8777                 :                :                          "a.attalign,\n"
                               8778                 :                :                          "a.attislocal,\n"
                               8779                 :                :                          "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"
                               8780                 :                :                          "array_to_string(a.attoptions, ', ') AS attoptions,\n"
                               8781                 :                :                          "CASE WHEN a.attcollation <> t.typcollation "
                               8782                 :                :                          "THEN a.attcollation ELSE 0 END AS attcollation,\n"
                               8783                 :                :                          "pg_catalog.array_to_string(ARRAY("
                               8784                 :                :                          "SELECT pg_catalog.quote_ident(option_name) || "
                               8785                 :                :                          "' ' || pg_catalog.quote_literal(option_value) "
                               8786                 :                :                          "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
                               8787                 :                :                          "ORDER BY option_name"
                               8788                 :                :                          "), E',\n    ') AS attfdwoptions,\n");
                               8789                 :                : 
                               8790                 :                :     /*
                               8791                 :                :      * Find out any NOT NULL markings for each column.  In 17 and up we have
                               8792                 :                :      * to read pg_constraint, and keep track whether it's NO INHERIT; in older
                               8793                 :                :      * versions we rely on pg_attribute.attnotnull.
                               8794                 :                :      *
                               8795                 :                :      * We also track whether the constraint was defined directly in this table
                               8796                 :                :      * or via an ancestor, for binary upgrade.
                               8797                 :                :      *
                               8798                 :                :      * Lastly, we need to know if the PK for the table involves each column;
                               8799                 :                :      * for columns that are there we need a NOT NULL marking even if there's
                               8800                 :                :      * no explicit constraint, to avoid the table having to be scanned for
                               8801                 :                :      * NULLs after the data is loaded when the PK is created, later in the
                               8802                 :                :      * dump; for this case we add throwaway constraints that are dropped once
                               8803                 :                :      * the PK is created.
                               8804                 :                :      */
  233 alvherre@alvh.no-ip.     8805         [ +  - ]:GNC         155 :     if (fout->remoteVersion >= 170000)
                               8806                 :            155 :         appendPQExpBufferStr(q,
                               8807                 :                :                              "co.conname AS notnull_name,\n"
                               8808                 :                :                              "co.connoinherit AS notnull_noinherit,\n"
                               8809                 :                :                              "copk.conname IS NOT NULL as notnull_is_pk,\n"
                               8810                 :                :                              "coalesce(NOT co.conislocal, true) AS notnull_inh,\n");
                               8811                 :                :     else
  233 alvherre@alvh.no-ip.     8812                 :UNC           0 :         appendPQExpBufferStr(q,
                               8813                 :                :                              "CASE WHEN a.attnotnull THEN '' ELSE NULL END AS notnull_name,\n"
                               8814                 :                :                              "false AS notnull_noinherit,\n"
                               8815                 :                :                              "copk.conname IS NOT NULL AS notnull_is_pk,\n"
                               8816                 :                :                              "NOT a.attislocal AS notnull_inh,\n");
                               8817                 :                : 
  860 tgl@sss.pgh.pa.us        8818         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 140000)
                               8819                 :            155 :         appendPQExpBufferStr(q,
                               8820                 :                :                              "a.attcompression AS attcompression,\n");
                               8821                 :                :     else
  860 tgl@sss.pgh.pa.us        8822                 :UBC           0 :         appendPQExpBufferStr(q,
                               8823                 :                :                              "'' AS attcompression,\n");
                               8824                 :                : 
  860 tgl@sss.pgh.pa.us        8825         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 100000)
                               8826                 :            155 :         appendPQExpBufferStr(q,
                               8827                 :                :                              "a.attidentity,\n");
                               8828                 :                :     else
  860 tgl@sss.pgh.pa.us        8829                 :UBC           0 :         appendPQExpBufferStr(q,
                               8830                 :                :                              "'' AS attidentity,\n");
                               8831                 :                : 
  860 tgl@sss.pgh.pa.us        8832         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 110000)
                               8833                 :            155 :         appendPQExpBufferStr(q,
                               8834                 :                :                              "CASE WHEN a.atthasmissing AND NOT a.attisdropped "
                               8835                 :                :                              "THEN a.attmissingval ELSE null END AS attmissingval,\n");
                               8836                 :                :     else
  860 tgl@sss.pgh.pa.us        8837                 :UBC           0 :         appendPQExpBufferStr(q,
                               8838                 :                :                              "NULL AS attmissingval,\n");
                               8839                 :                : 
  860 tgl@sss.pgh.pa.us        8840         [ +  - ]:CBC         155 :     if (fout->remoteVersion >= 120000)
                               8841                 :            155 :         appendPQExpBufferStr(q,
                               8842                 :                :                              "a.attgenerated\n");
                               8843                 :                :     else
  860 tgl@sss.pgh.pa.us        8844                 :UBC           0 :         appendPQExpBufferStr(q,
                               8845                 :                :                              "'' AS attgenerated\n");
                               8846                 :                : 
                               8847                 :                :     /* need left join to pg_type to not fail on dropped columns ... */
  860 tgl@sss.pgh.pa.us        8848                 :CBC         155 :     appendPQExpBuffer(q,
                               8849                 :                :                       "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               8850                 :                :                       "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) "
                               8851                 :                :                       "LEFT JOIN pg_catalog.pg_type t "
                               8852                 :                :                       "ON (a.atttypid = t.oid)\n",
                               8853                 :                :                       tbloids->data);
                               8854                 :                : 
                               8855                 :                :     /*
                               8856                 :                :      * In versions 16 and up, we need pg_constraint for explicit NOT NULL
                               8857                 :                :      * entries.  Also, we need to know if the NOT NULL for each column is
                               8858                 :                :      * backing a primary key.
                               8859                 :                :      */
  233 alvherre@alvh.no-ip.     8860         [ +  - ]:GNC         155 :     if (fout->remoteVersion >= 170000)
                               8861                 :            155 :         appendPQExpBufferStr(q,
                               8862                 :                :                              " LEFT JOIN pg_catalog.pg_constraint co ON "
                               8863                 :                :                              "(a.attrelid = co.conrelid\n"
                               8864                 :                :                              "   AND co.contype = 'n' AND "
                               8865                 :                :                              "co.conkey = array[a.attnum])\n");
                               8866                 :                : 
                               8867                 :            155 :     appendPQExpBufferStr(q,
                               8868                 :                :                          "LEFT JOIN pg_catalog.pg_constraint copk ON "
                               8869                 :                :                          "(copk.conrelid = src.tbloid\n"
                               8870                 :                :                          "   AND copk.contype = 'p' AND "
                               8871                 :                :                          "copk.conkey @> array[a.attnum])\n"
                               8872                 :                :                          "WHERE a.attnum > 0::pg_catalog.int2\n"
                               8873                 :                :                          "ORDER BY a.attrelid, a.attnum");
                               8874                 :                : 
  860 tgl@sss.pgh.pa.us        8875                 :CBC         155 :     res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               8876                 :                : 
                               8877                 :            155 :     ntups = PQntuples(res);
                               8878                 :                : 
                               8879                 :            155 :     i_attrelid = PQfnumber(res, "attrelid");
                               8880                 :            155 :     i_attnum = PQfnumber(res, "attnum");
                               8881                 :            155 :     i_attname = PQfnumber(res, "attname");
                               8882                 :            155 :     i_atttypname = PQfnumber(res, "atttypname");
                               8883                 :            155 :     i_attstattarget = PQfnumber(res, "attstattarget");
                               8884                 :            155 :     i_attstorage = PQfnumber(res, "attstorage");
                               8885                 :            155 :     i_typstorage = PQfnumber(res, "typstorage");
                               8886                 :            155 :     i_attidentity = PQfnumber(res, "attidentity");
                               8887                 :            155 :     i_attgenerated = PQfnumber(res, "attgenerated");
                               8888                 :            155 :     i_attisdropped = PQfnumber(res, "attisdropped");
                               8889                 :            155 :     i_attlen = PQfnumber(res, "attlen");
                               8890                 :            155 :     i_attalign = PQfnumber(res, "attalign");
                               8891                 :            155 :     i_attislocal = PQfnumber(res, "attislocal");
  233 alvherre@alvh.no-ip.     8892                 :GNC         155 :     i_notnull_name = PQfnumber(res, "notnull_name");
                               8893                 :            155 :     i_notnull_noinherit = PQfnumber(res, "notnull_noinherit");
                               8894                 :            155 :     i_notnull_is_pk = PQfnumber(res, "notnull_is_pk");
                               8895                 :            155 :     i_notnull_inh = PQfnumber(res, "notnull_inh");
  860 tgl@sss.pgh.pa.us        8896                 :CBC         155 :     i_attoptions = PQfnumber(res, "attoptions");
                               8897                 :            155 :     i_attcollation = PQfnumber(res, "attcollation");
                               8898                 :            155 :     i_attcompression = PQfnumber(res, "attcompression");
                               8899                 :            155 :     i_attfdwoptions = PQfnumber(res, "attfdwoptions");
                               8900                 :            155 :     i_attmissingval = PQfnumber(res, "attmissingval");
                               8901                 :            155 :     i_atthasdef = PQfnumber(res, "atthasdef");
                               8902                 :                : 
                               8903                 :                :     /* Within the next loop, we'll accumulate OIDs of tables with defaults */
  368 alvherre@alvh.no-ip.     8904                 :            155 :     resetPQExpBuffer(tbloids);
                               8905                 :            155 :     appendPQExpBufferChar(tbloids, '{');
                               8906                 :                : 
                               8907                 :                :     /*
                               8908                 :                :      * Outer loop iterates once per table, not once per row.  Incrementing of
                               8909                 :                :      * r is handled by the inner loop.
                               8910                 :                :      */
  860 tgl@sss.pgh.pa.us        8911                 :            155 :     curtblindx = -1;
                               8912         [ +  + ]:           5600 :     for (int r = 0; r < ntups;)
                               8913                 :                :     {
                               8914                 :           5445 :         Oid         attrelid = atooid(PQgetvalue(res, r, i_attrelid));
                               8915                 :           5445 :         TableInfo  *tbinfo = NULL;
                               8916                 :                :         int         numatts;
                               8917                 :                :         bool        hasdefaults;
                               8918                 :                :         int         notnullcount;
                               8919                 :                : 
                               8920                 :                :         /* Count rows for this table */
                               8921         [ +  + ]:          19859 :         for (numatts = 1; numatts < ntups - r; numatts++)
                               8922         [ +  + ]:          19759 :             if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid)
                               8923                 :           5345 :                 break;
                               8924                 :                : 
                               8925                 :                :         /*
                               8926                 :                :          * Locate the associated TableInfo; we rely on tblinfo[] being in OID
                               8927                 :                :          * order.
                               8928                 :                :          */
                               8929         [ +  - ]:          27372 :         while (++curtblindx < numTables)
                               8930                 :                :         {
                               8931                 :          27372 :             tbinfo = &tblinfo[curtblindx];
                               8932         [ +  + ]:          27372 :             if (tbinfo->dobj.catId.oid == attrelid)
                               8933                 :           5445 :                 break;
                               8934                 :                :         }
                               8935         [ -  + ]:           5445 :         if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        8936                 :UBC           0 :             pg_fatal("unrecognized table OID %u", attrelid);
                               8937                 :                :         /* cross-check that we only got requested tables */
  860 tgl@sss.pgh.pa.us        8938         [ +  - ]:CBC        5445 :         if (tbinfo->relkind == RELKIND_SEQUENCE ||
                               8939         [ -  + ]:           5445 :             !tbinfo->interesting)
  737 tgl@sss.pgh.pa.us        8940                 :UBC           0 :             pg_fatal("unexpected column data for table \"%s\"",
                               8941                 :                :                      tbinfo->dobj.name);
                               8942                 :                : 
  233 alvherre@alvh.no-ip.     8943                 :GNC        5445 :         notnullcount = 0;
                               8944                 :                : 
                               8945                 :                :         /* Save data for this table */
  860 tgl@sss.pgh.pa.us        8946                 :CBC        5445 :         tbinfo->numatts = numatts;
                               8947                 :           5445 :         tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *));
                               8948                 :           5445 :         tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *));
                               8949                 :           5445 :         tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int));
                               8950                 :           5445 :         tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char));
                               8951                 :           5445 :         tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char));
                               8952                 :           5445 :         tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char));
                               8953                 :           5445 :         tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char));
                               8954                 :           5445 :         tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool));
                               8955                 :           5445 :         tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int));
                               8956                 :           5445 :         tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char));
                               8957                 :           5445 :         tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool));
                               8958                 :           5445 :         tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               8959                 :           5445 :         tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid));
                               8960                 :           5445 :         tbinfo->attcompression = (char *) pg_malloc(numatts * sizeof(char));
                               8961                 :           5445 :         tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *));
                               8962                 :           5445 :         tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *));
  233 alvherre@alvh.no-ip.     8963                 :GNC        5445 :         tbinfo->notnull_constrs = (char **) pg_malloc(numatts * sizeof(char *));
                               8964                 :           5445 :         tbinfo->notnull_noinh = (bool *) pg_malloc(numatts * sizeof(bool));
                               8965                 :           5445 :         tbinfo->notnull_throwaway = (bool *) pg_malloc(numatts * sizeof(bool));
                               8966                 :           5445 :         tbinfo->notnull_inh = (bool *) pg_malloc(numatts * sizeof(bool));
  860 tgl@sss.pgh.pa.us        8967                 :CBC        5445 :         tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *));
 8010                          8968                 :           5445 :         hasdefaults = false;
                               8969                 :                : 
  860                          8970         [ +  + ]:          25304 :         for (int j = 0; j < numatts; j++, r++)
                               8971                 :                :         {
  233 alvherre@alvh.no-ip.     8972                 :GNC       19859 :             bool        use_named_notnull = false;
                               8973                 :          19859 :             bool        use_unnamed_notnull = false;
                               8974                 :          19859 :             bool        use_throwaway_notnull = false;
                               8975                 :                : 
  860 tgl@sss.pgh.pa.us        8976         [ -  + ]:CBC       19859 :             if (j + 1 != atoi(PQgetvalue(res, r, i_attnum)))
  737 tgl@sss.pgh.pa.us        8977                 :UBC           0 :                 pg_fatal("invalid column numbering in table \"%s\"",
                               8978                 :                :                          tbinfo->dobj.name);
  860 tgl@sss.pgh.pa.us        8979                 :CBC       19859 :             tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname));
                               8980                 :          19859 :             tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname));
   92 peter@eisentraut.org     8981         [ +  + ]:GNC       19859 :             if (PQgetisnull(res, r, i_attstattarget))
                               8982                 :          19819 :                 tbinfo->attstattarget[j] = -1;
                               8983                 :                :             else
                               8984                 :             40 :                 tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget));
  860 tgl@sss.pgh.pa.us        8985                 :CBC       19859 :             tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage));
                               8986                 :          19859 :             tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage));
                               8987                 :          19859 :             tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity));
                               8988                 :          19859 :             tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated));
 2565 peter_e@gmx.net          8989   [ +  +  +  + ]:          19859 :             tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS);
  860 tgl@sss.pgh.pa.us        8990                 :          19859 :             tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't');
                               8991                 :          19859 :             tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen));
                               8992                 :          19859 :             tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign));
                               8993                 :          19859 :             tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't');
                               8994                 :                : 
                               8995                 :                :             /*
                               8996                 :                :              * Not-null constraints require a jumping through a few hoops.
                               8997                 :                :              * First, if the user has specified a constraint name that's not
                               8998                 :                :              * the system-assigned default name, then we need to preserve
                               8999                 :                :              * that. But if they haven't, then we don't want to use the
                               9000                 :                :              * verbose syntax in the dump output. (Also, in versions prior to
                               9001                 :                :              * 17, there was no constraint name at all.)
                               9002                 :                :              *
                               9003                 :                :              * (XXX Comparing the name this way to a supposed default name is
                               9004                 :                :              * a bit of a hack, but it beats having to store a boolean flag in
                               9005                 :                :              * pg_constraint just for this, or having to compute the knowledge
                               9006                 :                :              * at pg_dump time from the server.)
                               9007                 :                :              *
                               9008                 :                :              * We also need to know if a column is part of the primary key. In
                               9009                 :                :              * that case, we want to mark the column as not-null at table
                               9010                 :                :              * creation time, so that the table doesn't have to be scanned to
                               9011                 :                :              * check for nulls when the PK is created afterwards; this is
                               9012                 :                :              * especially critical during pg_upgrade (where the data would not
                               9013                 :                :              * be scanned at all otherwise.)  If the column is part of the PK
                               9014                 :                :              * and does not have any other not-null constraint, then we
                               9015                 :                :              * fabricate a throwaway constraint name that we later use to
                               9016                 :                :              * remove the constraint after the PK has been created.
                               9017                 :                :              *
                               9018                 :                :              * For inheritance child tables, we don't want to print not-null
                               9019                 :                :              * when the constraint was defined at the parent level instead of
                               9020                 :                :              * locally.
                               9021                 :                :              */
                               9022                 :                : 
                               9023                 :                :             /*
                               9024                 :                :              * We use notnull_inh to suppress unwanted not-null constraints in
                               9025                 :                :              * inheritance children, when said constraints come from the
                               9026                 :                :              * parent(s).
                               9027                 :                :              */
  233 alvherre@alvh.no-ip.     9028                 :GNC       19859 :             tbinfo->notnull_inh[j] = PQgetvalue(res, r, i_notnull_inh)[0] == 't';
                               9029                 :                : 
                               9030         [ -  + ]:          19859 :             if (fout->remoteVersion < 170000)
                               9031                 :                :             {
  233 alvherre@alvh.no-ip.     9032         [ #  # ]:UNC           0 :                 if (!PQgetisnull(res, r, i_notnull_name) &&
                               9033         [ #  # ]:              0 :                     dopt->binary_upgrade &&
                               9034         [ #  # ]:              0 :                     !tbinfo->ispartition &&
                               9035         [ #  # ]:              0 :                     tbinfo->notnull_inh[j])
                               9036                 :                :                 {
                               9037                 :              0 :                     use_named_notnull = true;
                               9038                 :                :                     /* XXX should match ChooseConstraintName better */
                               9039                 :              0 :                     tbinfo->notnull_constrs[j] =
                               9040                 :              0 :                         psprintf("%s_%s_not_null", tbinfo->dobj.name,
                               9041                 :              0 :                                  tbinfo->attnames[j]);
                               9042                 :                :                 }
                               9043         [ #  # ]:              0 :                 else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
                               9044                 :              0 :                     use_throwaway_notnull = true;
                               9045         [ #  # ]:              0 :                 else if (!PQgetisnull(res, r, i_notnull_name))
                               9046                 :              0 :                     use_unnamed_notnull = true;
                               9047                 :                :             }
                               9048                 :                :             else
                               9049                 :                :             {
  233 alvherre@alvh.no-ip.     9050         [ +  + ]:GNC       19859 :                 if (!PQgetisnull(res, r, i_notnull_name))
                               9051                 :                :                 {
                               9052                 :                :                     /*
                               9053                 :                :                      * In binary upgrade of inheritance child tables, must
                               9054                 :                :                      * have a constraint name that we can UPDATE later.
                               9055                 :                :                      */
                               9056         [ +  + ]:           1211 :                     if (dopt->binary_upgrade &&
                               9057         [ +  + ]:            132 :                         !tbinfo->ispartition &&
                               9058         [ +  + ]:             87 :                         tbinfo->notnull_inh[j])
                               9059                 :                :                     {
                               9060                 :             16 :                         use_named_notnull = true;
                               9061                 :             16 :                         tbinfo->notnull_constrs[j] =
                               9062                 :             16 :                             pstrdup(PQgetvalue(res, r, i_notnull_name));
                               9063                 :                : 
                               9064                 :                :                     }
                               9065                 :                :                     else
                               9066                 :                :                     {
                               9067                 :                :                         char       *default_name;
                               9068                 :                : 
                               9069                 :                :                         /* XXX should match ChooseConstraintName better */
                               9070                 :           1195 :                         default_name = psprintf("%s_%s_not_null", tbinfo->dobj.name,
                               9071                 :           1195 :                                                 tbinfo->attnames[j]);
                               9072         [ +  + ]:           1195 :                         if (strcmp(default_name,
                               9073                 :           1195 :                                    PQgetvalue(res, r, i_notnull_name)) == 0)
                               9074                 :            746 :                             use_unnamed_notnull = true;
                               9075                 :                :                         else
                               9076                 :                :                         {
                               9077                 :            449 :                             use_named_notnull = true;
                               9078                 :            449 :                             tbinfo->notnull_constrs[j] =
                               9079                 :            449 :                                 pstrdup(PQgetvalue(res, r, i_notnull_name));
                               9080                 :                :                         }
                               9081                 :                :                     }
                               9082                 :                :                 }
                               9083         [ +  + ]:          18648 :                 else if (PQgetvalue(res, r, i_notnull_is_pk)[0] == 't')
                               9084                 :            819 :                     use_throwaway_notnull = true;
                               9085                 :                :             }
                               9086                 :                : 
                               9087         [ +  + ]:          19859 :             if (use_unnamed_notnull)
                               9088                 :                :             {
                               9089                 :            746 :                 tbinfo->notnull_constrs[j] = "";
                               9090                 :            746 :                 tbinfo->notnull_throwaway[j] = false;
                               9091                 :                :             }
                               9092         [ +  + ]:          19113 :             else if (use_named_notnull)
                               9093                 :                :             {
                               9094                 :                :                 /* The name itself has already been determined */
                               9095                 :            465 :                 tbinfo->notnull_throwaway[j] = false;
                               9096                 :                :             }
                               9097         [ +  + ]:          18648 :             else if (use_throwaway_notnull)
                               9098                 :                :             {
                               9099                 :           1638 :                 tbinfo->notnull_constrs[j] =
                               9100                 :            819 :                     psprintf("pgdump_throwaway_notnull_%d", notnullcount++);
                               9101                 :            819 :                 tbinfo->notnull_throwaway[j] = true;
                               9102                 :            819 :                 tbinfo->notnull_inh[j] = false;
                               9103                 :                :             }
                               9104                 :                :             else
                               9105                 :                :             {
                               9106                 :          17829 :                 tbinfo->notnull_constrs[j] = NULL;
                               9107                 :          17829 :                 tbinfo->notnull_throwaway[j] = false;
                               9108                 :                :             }
                               9109                 :                : 
                               9110                 :                :             /*
                               9111                 :                :              * Throwaway constraints must always be NO INHERIT; otherwise do
                               9112                 :                :              * what the catalog says.
                               9113                 :                :              */
                               9114         [ +  + ]:          38899 :             tbinfo->notnull_noinh[j] = use_throwaway_notnull ||
                               9115         [ +  + ]:          19040 :                 PQgetvalue(res, r, i_notnull_noinherit)[0] == 't';
                               9116                 :                : 
  860 tgl@sss.pgh.pa.us        9117                 :CBC       19859 :             tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions));
                               9118                 :          19859 :             tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation));
                               9119                 :          19859 :             tbinfo->attcompression[j] = *(PQgetvalue(res, r, i_attcompression));
                               9120                 :          19859 :             tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions));
                               9121                 :          19859 :             tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval));
 7168 bruce@momjian.us         9122                 :          19859 :             tbinfo->attrdefs[j] = NULL; /* fix below */
  860 tgl@sss.pgh.pa.us        9123         [ +  + ]:          19859 :             if (PQgetvalue(res, r, i_atthasdef)[0] == 't')
 8010                          9124                 :            907 :                 hasdefaults = true;
                               9125                 :                :         }
                               9126                 :                : 
  860                          9127         [ +  + ]:           5445 :         if (hasdefaults)
                               9128                 :                :         {
                               9129                 :                :             /* Collect OIDs of interesting tables that have defaults */
  368 alvherre@alvh.no-ip.     9130         [ +  + ]:            753 :             if (tbloids->len > 1) /* do we have more than the '{'? */
                               9131                 :            702 :                 appendPQExpBufferChar(tbloids, ',');
                               9132                 :            753 :             appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid);
                               9133                 :                :         }
                               9134                 :                :     }
                               9135                 :                : 
  860 tgl@sss.pgh.pa.us        9136                 :            155 :     PQclear(res);
                               9137                 :                : 
                               9138                 :                :     /*
                               9139                 :                :      * Now get info about column defaults.  This is skipped for a data-only
                               9140                 :                :      * dump, as it is only needed for table schemas.
                               9141                 :                :      */
  368 alvherre@alvh.no-ip.     9142   [ +  +  +  + ]:            155 :     if (!dopt->dataOnly && tbloids->len > 1)
                               9143                 :                :     {
                               9144                 :                :         AttrDefInfo *attrdefs;
                               9145                 :                :         int         numDefaults;
  860 tgl@sss.pgh.pa.us        9146                 :             47 :         TableInfo  *tbinfo = NULL;
                               9147                 :                : 
                               9148                 :             47 :         pg_log_info("finding table default expressions");
                               9149                 :                : 
  368 alvherre@alvh.no-ip.     9150                 :             47 :         appendPQExpBufferChar(tbloids, '}');
                               9151                 :                : 
  860 tgl@sss.pgh.pa.us        9152                 :             47 :         printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, "
                               9153                 :                :                           "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n"
                               9154                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9155                 :                :                           "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n"
                               9156                 :                :                           "ORDER BY a.adrelid, a.adnum",
                               9157                 :                :                           tbloids->data);
                               9158                 :                : 
                               9159                 :             47 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9160                 :                : 
                               9161                 :             47 :         numDefaults = PQntuples(res);
                               9162                 :             47 :         attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
                               9163                 :                : 
                               9164                 :             47 :         curtblindx = -1;
                               9165         [ +  + ]:            914 :         for (int j = 0; j < numDefaults; j++)
                               9166                 :                :         {
                               9167                 :            867 :             Oid         adtableoid = atooid(PQgetvalue(res, j, 0));
                               9168                 :            867 :             Oid         adoid = atooid(PQgetvalue(res, j, 1));
                               9169                 :            867 :             Oid         adrelid = atooid(PQgetvalue(res, j, 2));
                               9170                 :            867 :             int         adnum = atoi(PQgetvalue(res, j, 3));
                               9171                 :            867 :             char       *adsrc = PQgetvalue(res, j, 4);
                               9172                 :                : 
                               9173                 :                :             /*
                               9174                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9175                 :                :              * OID order.
                               9176                 :                :              */
                               9177   [ +  +  +  + ]:            867 :             if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid)
                               9178                 :                :             {
                               9179         [ +  - ]:          15529 :                 while (++curtblindx < numTables)
                               9180                 :                :                 {
                               9181                 :          15529 :                     tbinfo = &tblinfo[curtblindx];
                               9182         [ +  + ]:          15529 :                     if (tbinfo->dobj.catId.oid == adrelid)
                               9183                 :            719 :                         break;
                               9184                 :                :                 }
                               9185         [ -  + ]:            719 :                 if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        9186                 :UBC           0 :                     pg_fatal("unrecognized table OID %u", adrelid);
                               9187                 :                :             }
                               9188                 :                : 
  860 tgl@sss.pgh.pa.us        9189   [ +  -  -  + ]:CBC         867 :             if (adnum <= 0 || adnum > tbinfo->numatts)
  737 tgl@sss.pgh.pa.us        9190                 :UBC           0 :                 pg_fatal("invalid adnum value %d for table \"%s\"",
                               9191                 :                :                          adnum, tbinfo->dobj.name);
                               9192                 :                : 
                               9193                 :                :             /*
                               9194                 :                :              * dropped columns shouldn't have defaults, but just in case,
                               9195                 :                :              * ignore 'em
                               9196                 :                :              */
  860 tgl@sss.pgh.pa.us        9197         [ -  + ]:CBC         867 :             if (tbinfo->attisdropped[adnum - 1])
  860 tgl@sss.pgh.pa.us        9198                 :UBC           0 :                 continue;
                               9199                 :                : 
  860 tgl@sss.pgh.pa.us        9200                 :CBC         867 :             attrdefs[j].dobj.objType = DO_ATTRDEF;
                               9201                 :            867 :             attrdefs[j].dobj.catId.tableoid = adtableoid;
                               9202                 :            867 :             attrdefs[j].dobj.catId.oid = adoid;
                               9203                 :            867 :             AssignDumpId(&attrdefs[j].dobj);
                               9204                 :            867 :             attrdefs[j].adtable = tbinfo;
                               9205                 :            867 :             attrdefs[j].adnum = adnum;
                               9206                 :            867 :             attrdefs[j].adef_expr = pg_strdup(adsrc);
                               9207                 :                : 
                               9208                 :            867 :             attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
                               9209                 :            867 :             attrdefs[j].dobj.namespace = tbinfo->dobj.namespace;
                               9210                 :                : 
                               9211                 :            867 :             attrdefs[j].dobj.dump = tbinfo->dobj.dump;
                               9212                 :                : 
                               9213                 :                :             /*
                               9214                 :                :              * Figure out whether the default/generation expression should be
                               9215                 :                :              * dumped as part of the main CREATE TABLE (or similar) command or
                               9216                 :                :              * as a separate ALTER TABLE (or similar) command. The preference
                               9217                 :                :              * is to put it into the CREATE command, but in some cases that's
                               9218                 :                :              * not possible.
                               9219                 :                :              */
                               9220         [ +  + ]:            867 :             if (tbinfo->attgenerated[adnum - 1])
                               9221                 :                :             {
                               9222                 :                :                 /*
                               9223                 :                :                  * Column generation expressions cannot be dumped separately,
                               9224                 :                :                  * because there is no syntax for it.  By setting separate to
                               9225                 :                :                  * false here we prevent the "default" from being processed as
                               9226                 :                :                  * its own dumpable object.  Later, flagInhAttrs() will mark
                               9227                 :                :                  * it as not to be dumped at all, if possible (that is, if it
                               9228                 :                :                  * can be inherited from a parent).
                               9229                 :                :                  */
                               9230                 :            360 :                 attrdefs[j].separate = false;
                               9231                 :                :             }
                               9232         [ +  + ]:            507 :             else if (tbinfo->relkind == RELKIND_VIEW)
                               9233                 :                :             {
                               9234                 :                :                 /*
                               9235                 :                :                  * Defaults on a VIEW must always be dumped as separate ALTER
                               9236                 :                :                  * TABLE commands.
                               9237                 :                :                  */
                               9238                 :             36 :                 attrdefs[j].separate = true;
                               9239                 :                :             }
                               9240         [ +  + ]:            471 :             else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1))
                               9241                 :                :             {
                               9242                 :                :                 /* column will be suppressed, print default separately */
                               9243                 :              4 :                 attrdefs[j].separate = true;
                               9244                 :                :             }
                               9245                 :                :             else
                               9246                 :                :             {
                               9247                 :            467 :                 attrdefs[j].separate = false;
                               9248                 :                :             }
                               9249                 :                : 
                               9250         [ +  + ]:            867 :             if (!attrdefs[j].separate)
                               9251                 :                :             {
                               9252                 :                :                 /*
                               9253                 :                :                  * Mark the default as needing to appear before the table, so
                               9254                 :                :                  * that any dependencies it has must be emitted before the
                               9255                 :                :                  * CREATE TABLE.  If this is not possible, we'll change to
                               9256                 :                :                  * "separate" mode while sorting dependencies.
                               9257                 :                :                  */
                               9258                 :            827 :                 addObjectDependency(&tbinfo->dobj,
                               9259                 :            827 :                                     attrdefs[j].dobj.dumpId);
                               9260                 :                :             }
                               9261                 :                : 
                               9262                 :            867 :             tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
                               9263                 :                :         }
                               9264                 :                : 
                               9265                 :             47 :         PQclear(res);
                               9266                 :                :     }
                               9267                 :                : 
                               9268                 :                :     /*
                               9269                 :                :      * Get info about table CHECK constraints.  This is skipped for a
                               9270                 :                :      * data-only dump, as it is only needed for table schemas.
                               9271                 :                :      */
                               9272   [ +  +  +  + ]:            155 :     if (!dopt->dataOnly && checkoids->len > 2)
                               9273                 :                :     {
                               9274                 :                :         ConstraintInfo *constrs;
                               9275                 :                :         int         numConstrs;
                               9276                 :                :         int         i_tableoid;
                               9277                 :                :         int         i_oid;
                               9278                 :                :         int         i_conrelid;
                               9279                 :                :         int         i_conname;
                               9280                 :                :         int         i_consrc;
                               9281                 :                :         int         i_conislocal;
                               9282                 :                :         int         i_convalidated;
                               9283                 :                : 
                               9284                 :             64 :         pg_log_info("finding table check constraints");
                               9285                 :                : 
                               9286                 :             64 :         resetPQExpBuffer(q);
                               9287                 :             64 :         appendPQExpBuffer(q,
                               9288                 :                :                           "SELECT c.tableoid, c.oid, conrelid, conname, "
                               9289                 :                :                           "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "
                               9290                 :                :                           "conislocal, convalidated "
                               9291                 :                :                           "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n"
                               9292                 :                :                           "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n"
                               9293                 :                :                           "WHERE contype = 'c' "
                               9294                 :                :                           "ORDER BY c.conrelid, c.conname",
                               9295                 :                :                           checkoids->data);
                               9296                 :                : 
                               9297                 :             64 :         res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
                               9298                 :                : 
                               9299                 :             64 :         numConstrs = PQntuples(res);
                               9300                 :             64 :         constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
                               9301                 :                : 
                               9302                 :             64 :         i_tableoid = PQfnumber(res, "tableoid");
                               9303                 :             64 :         i_oid = PQfnumber(res, "oid");
                               9304                 :             64 :         i_conrelid = PQfnumber(res, "conrelid");
                               9305                 :             64 :         i_conname = PQfnumber(res, "conname");
                               9306                 :             64 :         i_consrc = PQfnumber(res, "consrc");
                               9307                 :             64 :         i_conislocal = PQfnumber(res, "conislocal");
                               9308                 :             64 :         i_convalidated = PQfnumber(res, "convalidated");
                               9309                 :                : 
                               9310                 :                :         /* As above, this loop iterates once per table, not once per row */
                               9311                 :             64 :         curtblindx = -1;
                               9312         [ +  + ]:            504 :         for (int j = 0; j < numConstrs;)
                               9313                 :                :         {
                               9314                 :            440 :             Oid         conrelid = atooid(PQgetvalue(res, j, i_conrelid));
                               9315                 :            440 :             TableInfo  *tbinfo = NULL;
                               9316                 :                :             int         numcons;
                               9317                 :                : 
                               9318                 :                :             /* Count rows for this table */
                               9319         [ +  + ]:            578 :             for (numcons = 1; numcons < numConstrs - j; numcons++)
                               9320         [ +  + ]:            514 :                 if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid)
                               9321                 :            376 :                     break;
                               9322                 :                : 
                               9323                 :                :             /*
                               9324                 :                :              * Locate the associated TableInfo; we rely on tblinfo[] being in
                               9325                 :                :              * OID order.
                               9326                 :                :              */
                               9327         [ +  - ]:          18295 :             while (++curtblindx < numTables)
                               9328                 :                :             {
                               9329                 :          18295 :                 tbinfo = &tblinfo[curtblindx];
                               9330         [ +  + ]:          18295 :                 if (tbinfo->dobj.catId.oid == conrelid)
                               9331                 :            440 :                     break;
                               9332                 :                :             }
                               9333         [ -  + ]:            440 :             if (curtblindx >= numTables)
  737 tgl@sss.pgh.pa.us        9334                 :UBC           0 :                 pg_fatal("unrecognized table OID %u", conrelid);
                               9335                 :                : 
  860 tgl@sss.pgh.pa.us        9336         [ -  + ]:CBC         440 :             if (numcons != tbinfo->ncheck)
                               9337                 :                :             {
 1840 peter@eisentraut.org     9338                 :UBC           0 :                 pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d",
                               9339                 :                :                                       "expected %d check constraints on table \"%s\" but found %d",
                               9340                 :                :                                       tbinfo->ncheck),
                               9341                 :                :                              tbinfo->ncheck, tbinfo->dobj.name, numcons);
  737 tgl@sss.pgh.pa.us        9342                 :              0 :                 pg_log_error_hint("The system catalogs might be corrupted.");
 4441 rhaas@postgresql.org     9343                 :              0 :                 exit_nicely(1);
                               9344                 :                :             }
                               9345                 :                : 
  860 tgl@sss.pgh.pa.us        9346                 :CBC         440 :             tbinfo->checkexprs = constrs + j;
                               9347                 :                : 
                               9348         [ +  + ]:           1018 :             for (int c = 0; c < numcons; c++, j++)
                               9349                 :                :             {
                               9350                 :            578 :                 bool        validated = PQgetvalue(res, j, i_convalidated)[0] == 't';
                               9351                 :                : 
 7435                          9352                 :            578 :                 constrs[j].dobj.objType = DO_CONSTRAINT;
  860                          9353                 :            578 :                 constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
                               9354                 :            578 :                 constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid));
 7435                          9355                 :            578 :                 AssignDumpId(&constrs[j].dobj);
  860                          9356                 :            578 :                 constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname));
 7347                          9357                 :            578 :                 constrs[j].dobj.namespace = tbinfo->dobj.namespace;
 7435                          9358                 :            578 :                 constrs[j].contable = tbinfo;
                               9359                 :            578 :                 constrs[j].condomain = NULL;
                               9360                 :            578 :                 constrs[j].contype = 'c';
  860                          9361                 :            578 :                 constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc));
 5697                          9362                 :            578 :                 constrs[j].confrelid = InvalidOid;
 7435                          9363                 :            578 :                 constrs[j].conindex = 0;
 5373                          9364                 :            578 :                 constrs[j].condeferrable = false;
                               9365                 :            578 :                 constrs[j].condeferred = false;
  860                          9366                 :            578 :                 constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't');
                               9367                 :                : 
                               9368                 :                :                 /*
                               9369                 :                :                  * An unvalidated constraint needs to be dumped separately, so
                               9370                 :                :                  * that potentially-violating existing data is loaded before
                               9371                 :                :                  * the constraint.
                               9372                 :                :                  */
 4377 alvherre@alvh.no-ip.     9373                 :            578 :                 constrs[j].separate = !validated;
                               9374                 :                : 
 6618 tgl@sss.pgh.pa.us        9375                 :            578 :                 constrs[j].dobj.dump = tbinfo->dobj.dump;
                               9376                 :                : 
                               9377                 :                :                 /*
                               9378                 :                :                  * Mark the constraint as needing to appear before the table
                               9379                 :                :                  * --- this is so that any other dependencies of the
                               9380                 :                :                  * constraint will be emitted before we try to create the
                               9381                 :                :                  * table.  If the constraint is to be dumped separately, it
                               9382                 :                :                  * will be dumped after data is loaded anyway, so don't do it.
                               9383                 :                :                  * (There's an automatic dependency in the opposite direction
                               9384                 :                :                  * anyway, so don't need to add one manually here.)
                               9385                 :                :                  */
 4514 alvherre@alvh.no-ip.     9386         [ +  + ]:            578 :                 if (!constrs[j].separate)
 4525                          9387                 :            543 :                     addObjectDependency(&tbinfo->dobj,
                               9388                 :            543 :                                         constrs[j].dobj.dumpId);
                               9389                 :                : 
                               9390                 :                :                 /*
                               9391                 :                :                  * We will detect later whether the constraint must be split
                               9392                 :                :                  * out from the table definition.
                               9393                 :                :                  */
                               9394                 :                :             }
                               9395                 :                :         }
                               9396                 :                : 
  860 tgl@sss.pgh.pa.us        9397                 :             64 :         PQclear(res);
                               9398                 :                :     }
                               9399                 :                : 
 8290                          9400                 :            155 :     destroyPQExpBuffer(q);
  860                          9401                 :            155 :     destroyPQExpBuffer(tbloids);
                               9402                 :            155 :     destroyPQExpBuffer(checkoids);
10141 scrappy@hub.org          9403                 :            155 : }
                               9404                 :                : 
                               9405                 :                : /*
                               9406                 :                :  * Test whether a column should be printed as part of table's CREATE TABLE.
                               9407                 :                :  * Column number is zero-based.
                               9408                 :                :  *
                               9409                 :                :  * Normally this is always true, but it's false for dropped columns, as well
                               9410                 :                :  * as those that were inherited without any local definition.  (If we print
                               9411                 :                :  * such a column it will mistakenly get pg_attribute.attislocal set to true.)
                               9412                 :                :  * For partitions, it's always true, because we want the partitions to be
                               9413                 :                :  * created independently and ATTACH PARTITION used afterwards.
                               9414                 :                :  *
                               9415                 :                :  * In binary_upgrade mode, we must print all columns and fix the attislocal/
                               9416                 :                :  * attisdropped state later, so as to keep control of the physical column
                               9417                 :                :  * order.
                               9418                 :                :  *
                               9419                 :                :  * This function exists because there are scattered nonobvious places that
                               9420                 :                :  * must be kept in sync with this decision.
                               9421                 :                :  */
                               9422                 :                : bool
 1159 peter@eisentraut.org     9423                 :          35877 : shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno)
                               9424                 :                : {
 3470 alvherre@alvh.no-ip.     9425         [ +  + ]:          35877 :     if (dopt->binary_upgrade)
 4447 tgl@sss.pgh.pa.us        9426                 :           5853 :         return true;
 1770 alvherre@alvh.no-ip.     9427         [ +  + ]:          30024 :     if (tbinfo->attisdropped[colno])
                               9428                 :            347 :         return false;
                               9429   [ +  +  +  + ]:          29677 :     return (tbinfo->attislocal[colno] || tbinfo->ispartition);
                               9430                 :                : }
                               9431                 :                : 
                               9432                 :                : 
                               9433                 :                : /*
                               9434                 :                :  * getTSParsers:
                               9435                 :                :  *    read all text search parsers in the system catalogs and return them
                               9436                 :                :  *    in the TSParserInfo* structure
                               9437                 :                :  *
                               9438                 :                :  *  numTSParsers is set to the number of parsers read in
                               9439                 :                :  */
                               9440                 :                : TSParserInfo *
 4451 rhaas@postgresql.org     9441                 :            155 : getTSParsers(Archive *fout, int *numTSParsers)
                               9442                 :                : {
                               9443                 :                :     PGresult   *res;
                               9444                 :                :     int         ntups;
                               9445                 :                :     int         i;
                               9446                 :                :     PQExpBuffer query;
                               9447                 :                :     TSParserInfo *prsinfo;
                               9448                 :                :     int         i_tableoid;
                               9449                 :                :     int         i_oid;
                               9450                 :                :     int         i_prsname;
                               9451                 :                :     int         i_prsnamespace;
                               9452                 :                :     int         i_prsstart;
                               9453                 :                :     int         i_prstoken;
                               9454                 :                :     int         i_prsend;
                               9455                 :                :     int         i_prsheadline;
                               9456                 :                :     int         i_prslextype;
                               9457                 :                : 
 4415 peter_e@gmx.net          9458                 :            155 :     query = createPQExpBuffer();
                               9459                 :                : 
                               9460                 :                :     /*
                               9461                 :                :      * find all text search objects, including builtin ones; we filter out
                               9462                 :                :      * system-defined objects at dump-out time.
                               9463                 :                :      */
                               9464                 :                : 
 3800 heikki.linnakangas@i     9465                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
                               9466                 :                :                          "prsstart::oid, prstoken::oid, "
                               9467                 :                :                          "prsend::oid, prsheadline::oid, prslextype::oid "
                               9468                 :                :                          "FROM pg_ts_parser");
                               9469                 :                : 
 4450 rhaas@postgresql.org     9470                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9471                 :                : 
 6081 tgl@sss.pgh.pa.us        9472                 :            155 :     ntups = PQntuples(res);
                               9473                 :            155 :     *numTSParsers = ntups;
                               9474                 :                : 
 4524 bruce@momjian.us         9475                 :            155 :     prsinfo = (TSParserInfo *) pg_malloc(ntups * sizeof(TSParserInfo));
                               9476                 :                : 
 6081 tgl@sss.pgh.pa.us        9477                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               9478                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9479                 :            155 :     i_prsname = PQfnumber(res, "prsname");
                               9480                 :            155 :     i_prsnamespace = PQfnumber(res, "prsnamespace");
                               9481                 :            155 :     i_prsstart = PQfnumber(res, "prsstart");
                               9482                 :            155 :     i_prstoken = PQfnumber(res, "prstoken");
                               9483                 :            155 :     i_prsend = PQfnumber(res, "prsend");
                               9484                 :            155 :     i_prsheadline = PQfnumber(res, "prsheadline");
                               9485                 :            155 :     i_prslextype = PQfnumber(res, "prslextype");
                               9486                 :                : 
                               9487         [ +  + ]:            356 :     for (i = 0; i < ntups; i++)
                               9488                 :                :     {
                               9489                 :            201 :         prsinfo[i].dobj.objType = DO_TSPARSER;
                               9490                 :            201 :         prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9491                 :            201 :         prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9492                 :            201 :         AssignDumpId(&prsinfo[i].dobj);
 4524 bruce@momjian.us         9493                 :            201 :         prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
 4451 rhaas@postgresql.org     9494                 :            402 :         prsinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     9495                 :            201 :             findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)));
 6081 tgl@sss.pgh.pa.us        9496                 :            201 :         prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
                               9497                 :            201 :         prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
                               9498                 :            201 :         prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
                               9499                 :            201 :         prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
                               9500                 :            201 :         prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
                               9501                 :                : 
                               9502                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9503                 :            201 :         selectDumpableObject(&(prsinfo[i].dobj), fout);
                               9504                 :                :     }
                               9505                 :                : 
 6081 tgl@sss.pgh.pa.us        9506                 :            155 :     PQclear(res);
                               9507                 :                : 
                               9508                 :            155 :     destroyPQExpBuffer(query);
                               9509                 :                : 
                               9510                 :            155 :     return prsinfo;
                               9511                 :                : }
                               9512                 :                : 
                               9513                 :                : /*
                               9514                 :                :  * getTSDictionaries:
                               9515                 :                :  *    read all text search dictionaries in the system catalogs and return them
                               9516                 :                :  *    in the TSDictInfo* structure
                               9517                 :                :  *
                               9518                 :                :  *  numTSDicts is set to the number of dictionaries read in
                               9519                 :                :  */
                               9520                 :                : TSDictInfo *
 4451 rhaas@postgresql.org     9521                 :            155 : getTSDictionaries(Archive *fout, int *numTSDicts)
                               9522                 :                : {
                               9523                 :                :     PGresult   *res;
                               9524                 :                :     int         ntups;
                               9525                 :                :     int         i;
                               9526                 :                :     PQExpBuffer query;
                               9527                 :                :     TSDictInfo *dictinfo;
                               9528                 :                :     int         i_tableoid;
                               9529                 :                :     int         i_oid;
                               9530                 :                :     int         i_dictname;
                               9531                 :                :     int         i_dictnamespace;
                               9532                 :                :     int         i_dictowner;
                               9533                 :                :     int         i_dicttemplate;
                               9534                 :                :     int         i_dictinitoption;
                               9535                 :                : 
 4415 peter_e@gmx.net          9536                 :            155 :     query = createPQExpBuffer();
                               9537                 :                : 
  586 drowley@postgresql.o     9538                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, dictname, "
                               9539                 :                :                          "dictnamespace, dictowner, "
                               9540                 :                :                          "dicttemplate, dictinitoption "
                               9541                 :                :                          "FROM pg_ts_dict");
                               9542                 :                : 
 4450 rhaas@postgresql.org     9543                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9544                 :                : 
 6081 tgl@sss.pgh.pa.us        9545                 :            155 :     ntups = PQntuples(res);
                               9546                 :            155 :     *numTSDicts = ntups;
                               9547                 :                : 
 4524 bruce@momjian.us         9548                 :            155 :     dictinfo = (TSDictInfo *) pg_malloc(ntups * sizeof(TSDictInfo));
                               9549                 :                : 
 6081 tgl@sss.pgh.pa.us        9550                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               9551                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9552                 :            155 :     i_dictname = PQfnumber(res, "dictname");
                               9553                 :            155 :     i_dictnamespace = PQfnumber(res, "dictnamespace");
  835                          9554                 :            155 :     i_dictowner = PQfnumber(res, "dictowner");
 6081                          9555                 :            155 :     i_dictinitoption = PQfnumber(res, "dictinitoption");
                               9556                 :            155 :     i_dicttemplate = PQfnumber(res, "dicttemplate");
                               9557                 :                : 
                               9558         [ +  + ]:           4741 :     for (i = 0; i < ntups; i++)
                               9559                 :                :     {
                               9560                 :           4586 :         dictinfo[i].dobj.objType = DO_TSDICT;
                               9561                 :           4586 :         dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9562                 :           4586 :         dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9563                 :           4586 :         AssignDumpId(&dictinfo[i].dobj);
 4524 bruce@momjian.us         9564                 :           4586 :         dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
 4451 rhaas@postgresql.org     9565                 :           9172 :         dictinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     9566                 :           4586 :             findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)));
  835 tgl@sss.pgh.pa.us        9567                 :           4586 :         dictinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_dictowner));
 6081                          9568                 :           4586 :         dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
                               9569         [ +  + ]:           4586 :         if (PQgetisnull(res, i, i_dictinitoption))
                               9570                 :            201 :             dictinfo[i].dictinitoption = NULL;
                               9571                 :                :         else
 4524 bruce@momjian.us         9572                 :           4385 :             dictinfo[i].dictinitoption = pg_strdup(PQgetvalue(res, i, i_dictinitoption));
                               9573                 :                : 
                               9574                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9575                 :           4586 :         selectDumpableObject(&(dictinfo[i].dobj), fout);
                               9576                 :                :     }
                               9577                 :                : 
 6081 tgl@sss.pgh.pa.us        9578                 :            155 :     PQclear(res);
                               9579                 :                : 
                               9580                 :            155 :     destroyPQExpBuffer(query);
                               9581                 :                : 
                               9582                 :            155 :     return dictinfo;
                               9583                 :                : }
                               9584                 :                : 
                               9585                 :                : /*
                               9586                 :                :  * getTSTemplates:
                               9587                 :                :  *    read all text search templates in the system catalogs and return them
                               9588                 :                :  *    in the TSTemplateInfo* structure
                               9589                 :                :  *
                               9590                 :                :  *  numTSTemplates is set to the number of templates read in
                               9591                 :                :  */
                               9592                 :                : TSTemplateInfo *
 4451 rhaas@postgresql.org     9593                 :            155 : getTSTemplates(Archive *fout, int *numTSTemplates)
                               9594                 :                : {
                               9595                 :                :     PGresult   *res;
                               9596                 :                :     int         ntups;
                               9597                 :                :     int         i;
                               9598                 :                :     PQExpBuffer query;
                               9599                 :                :     TSTemplateInfo *tmplinfo;
                               9600                 :                :     int         i_tableoid;
                               9601                 :                :     int         i_oid;
                               9602                 :                :     int         i_tmplname;
                               9603                 :                :     int         i_tmplnamespace;
                               9604                 :                :     int         i_tmplinit;
                               9605                 :                :     int         i_tmpllexize;
                               9606                 :                : 
 4415 peter_e@gmx.net          9607                 :            155 :     query = createPQExpBuffer();
                               9608                 :                : 
 3800 heikki.linnakangas@i     9609                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
                               9610                 :                :                          "tmplnamespace, tmplinit::oid, tmpllexize::oid "
                               9611                 :                :                          "FROM pg_ts_template");
                               9612                 :                : 
 4450 rhaas@postgresql.org     9613                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9614                 :                : 
 6081 tgl@sss.pgh.pa.us        9615                 :            155 :     ntups = PQntuples(res);
                               9616                 :            155 :     *numTSTemplates = ntups;
                               9617                 :                : 
 4524 bruce@momjian.us         9618                 :            155 :     tmplinfo = (TSTemplateInfo *) pg_malloc(ntups * sizeof(TSTemplateInfo));
                               9619                 :                : 
 6081 tgl@sss.pgh.pa.us        9620                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               9621                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9622                 :            155 :     i_tmplname = PQfnumber(res, "tmplname");
                               9623                 :            155 :     i_tmplnamespace = PQfnumber(res, "tmplnamespace");
                               9624                 :            155 :     i_tmplinit = PQfnumber(res, "tmplinit");
                               9625                 :            155 :     i_tmpllexize = PQfnumber(res, "tmpllexize");
                               9626                 :                : 
                               9627         [ +  + ]:            976 :     for (i = 0; i < ntups; i++)
                               9628                 :                :     {
                               9629                 :            821 :         tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
                               9630                 :            821 :         tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9631                 :            821 :         tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9632                 :            821 :         AssignDumpId(&tmplinfo[i].dobj);
 4524 bruce@momjian.us         9633                 :            821 :         tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
 4451 rhaas@postgresql.org     9634                 :           1642 :         tmplinfo[i].dobj.namespace =
 1328 peter@eisentraut.org     9635                 :            821 :             findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)));
 6081 tgl@sss.pgh.pa.us        9636                 :            821 :         tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
                               9637                 :            821 :         tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
                               9638                 :                : 
                               9639                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9640                 :            821 :         selectDumpableObject(&(tmplinfo[i].dobj), fout);
                               9641                 :                :     }
                               9642                 :                : 
 6081 tgl@sss.pgh.pa.us        9643                 :            155 :     PQclear(res);
                               9644                 :                : 
                               9645                 :            155 :     destroyPQExpBuffer(query);
                               9646                 :                : 
                               9647                 :            155 :     return tmplinfo;
                               9648                 :                : }
                               9649                 :                : 
                               9650                 :                : /*
                               9651                 :                :  * getTSConfigurations:
                               9652                 :                :  *    read all text search configurations in the system catalogs and return
                               9653                 :                :  *    them in the TSConfigInfo* structure
                               9654                 :                :  *
                               9655                 :                :  *  numTSConfigs is set to the number of configurations read in
                               9656                 :                :  */
                               9657                 :                : TSConfigInfo *
 4451 rhaas@postgresql.org     9658                 :            155 : getTSConfigurations(Archive *fout, int *numTSConfigs)
                               9659                 :                : {
                               9660                 :                :     PGresult   *res;
                               9661                 :                :     int         ntups;
                               9662                 :                :     int         i;
                               9663                 :                :     PQExpBuffer query;
                               9664                 :                :     TSConfigInfo *cfginfo;
                               9665                 :                :     int         i_tableoid;
                               9666                 :                :     int         i_oid;
                               9667                 :                :     int         i_cfgname;
                               9668                 :                :     int         i_cfgnamespace;
                               9669                 :                :     int         i_cfgowner;
                               9670                 :                :     int         i_cfgparser;
                               9671                 :                : 
 4415 peter_e@gmx.net          9672                 :            155 :     query = createPQExpBuffer();
                               9673                 :                : 
  586 drowley@postgresql.o     9674                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, cfgname, "
                               9675                 :                :                          "cfgnamespace, cfgowner, cfgparser "
                               9676                 :                :                          "FROM pg_ts_config");
                               9677                 :                : 
 4450 rhaas@postgresql.org     9678                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9679                 :                : 
 6081 tgl@sss.pgh.pa.us        9680                 :            155 :     ntups = PQntuples(res);
                               9681                 :            155 :     *numTSConfigs = ntups;
                               9682                 :                : 
 4524 bruce@momjian.us         9683                 :            155 :     cfginfo = (TSConfigInfo *) pg_malloc(ntups * sizeof(TSConfigInfo));
                               9684                 :                : 
 6081 tgl@sss.pgh.pa.us        9685                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               9686                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9687                 :            155 :     i_cfgname = PQfnumber(res, "cfgname");
                               9688                 :            155 :     i_cfgnamespace = PQfnumber(res, "cfgnamespace");
  835                          9689                 :            155 :     i_cfgowner = PQfnumber(res, "cfgowner");
 6081                          9690                 :            155 :     i_cfgparser = PQfnumber(res, "cfgparser");
                               9691                 :                : 
                               9692         [ +  + ]:           4716 :     for (i = 0; i < ntups; i++)
                               9693                 :                :     {
                               9694                 :           4561 :         cfginfo[i].dobj.objType = DO_TSCONFIG;
                               9695                 :           4561 :         cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9696                 :           4561 :         cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9697                 :           4561 :         AssignDumpId(&cfginfo[i].dobj);
 4524 bruce@momjian.us         9698                 :           4561 :         cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
 4451 rhaas@postgresql.org     9699                 :           9122 :         cfginfo[i].dobj.namespace =
 1328 peter@eisentraut.org     9700                 :           4561 :             findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)));
  835 tgl@sss.pgh.pa.us        9701                 :           4561 :         cfginfo[i].rolname = getRoleName(PQgetvalue(res, i, i_cfgowner));
 6081                          9702                 :           4561 :         cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
                               9703                 :                : 
                               9704                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9705                 :           4561 :         selectDumpableObject(&(cfginfo[i].dobj), fout);
                               9706                 :                :     }
                               9707                 :                : 
 6081 tgl@sss.pgh.pa.us        9708                 :            155 :     PQclear(res);
                               9709                 :                : 
                               9710                 :            155 :     destroyPQExpBuffer(query);
                               9711                 :                : 
                               9712                 :            155 :     return cfginfo;
                               9713                 :                : }
                               9714                 :                : 
                               9715                 :                : /*
                               9716                 :                :  * getForeignDataWrappers:
                               9717                 :                :  *    read all foreign-data wrappers in the system catalogs and return
                               9718                 :                :  *    them in the FdwInfo* structure
                               9719                 :                :  *
                               9720                 :                :  *  numForeignDataWrappers is set to the number of fdws read in
                               9721                 :                :  */
                               9722                 :                : FdwInfo *
 4451 rhaas@postgresql.org     9723                 :            155 : getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
                               9724                 :                : {
                               9725                 :                :     PGresult   *res;
                               9726                 :                :     int         ntups;
                               9727                 :                :     int         i;
                               9728                 :                :     PQExpBuffer query;
                               9729                 :                :     FdwInfo    *fdwinfo;
                               9730                 :                :     int         i_tableoid;
                               9731                 :                :     int         i_oid;
                               9732                 :                :     int         i_fdwname;
                               9733                 :                :     int         i_fdwowner;
                               9734                 :                :     int         i_fdwhandler;
                               9735                 :                :     int         i_fdwvalidator;
                               9736                 :                :     int         i_fdwacl;
                               9737                 :                :     int         i_acldefault;
                               9738                 :                :     int         i_fdwoptions;
                               9739                 :                : 
 3718 sfrost@snowman.net       9740                 :            155 :     query = createPQExpBuffer();
                               9741                 :                : 
  586 drowley@postgresql.o     9742                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, fdwname, "
                               9743                 :                :                          "fdwowner, "
                               9744                 :                :                          "fdwhandler::pg_catalog.regproc, "
                               9745                 :                :                          "fdwvalidator::pg_catalog.regproc, "
                               9746                 :                :                          "fdwacl, "
                               9747                 :                :                          "acldefault('F', fdwowner) AS acldefault, "
                               9748                 :                :                          "array_to_string(ARRAY("
                               9749                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                               9750                 :                :                          "quote_literal(option_value) "
                               9751                 :                :                          "FROM pg_options_to_table(fdwoptions) "
                               9752                 :                :                          "ORDER BY option_name"
                               9753                 :                :                          "), E',\n    ') AS fdwoptions "
                               9754                 :                :                          "FROM pg_foreign_data_wrapper");
                               9755                 :                : 
 4450 rhaas@postgresql.org     9756                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9757                 :                : 
 5595 peter_e@gmx.net          9758                 :            155 :     ntups = PQntuples(res);
                               9759                 :            155 :     *numForeignDataWrappers = ntups;
                               9760                 :                : 
 4524 bruce@momjian.us         9761                 :            155 :     fdwinfo = (FdwInfo *) pg_malloc(ntups * sizeof(FdwInfo));
                               9762                 :                : 
 4952 heikki.linnakangas@i     9763                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 5595 peter_e@gmx.net          9764                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9765                 :            155 :     i_fdwname = PQfnumber(res, "fdwname");
  835 tgl@sss.pgh.pa.us        9766                 :            155 :     i_fdwowner = PQfnumber(res, "fdwowner");
 4803                          9767                 :            155 :     i_fdwhandler = PQfnumber(res, "fdwhandler");
 5528 peter_e@gmx.net          9768                 :            155 :     i_fdwvalidator = PQfnumber(res, "fdwvalidator");
 5595                          9769                 :            155 :     i_fdwacl = PQfnumber(res, "fdwacl");
  860 tgl@sss.pgh.pa.us        9770                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
 5595 peter_e@gmx.net          9771                 :            155 :     i_fdwoptions = PQfnumber(res, "fdwoptions");
                               9772                 :                : 
                               9773         [ +  + ]:            225 :     for (i = 0; i < ntups; i++)
                               9774                 :                :     {
                               9775                 :             70 :         fdwinfo[i].dobj.objType = DO_FDW;
 4952 heikki.linnakangas@i     9776                 :             70 :         fdwinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 5595 peter_e@gmx.net          9777                 :             70 :         fdwinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9778                 :             70 :         AssignDumpId(&fdwinfo[i].dobj);
 4524 bruce@momjian.us         9779                 :             70 :         fdwinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_fdwname));
 5595 peter_e@gmx.net          9780                 :             70 :         fdwinfo[i].dobj.namespace = NULL;
  860 tgl@sss.pgh.pa.us        9781                 :             70 :         fdwinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_fdwacl));
                               9782                 :             70 :         fdwinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               9783                 :             70 :         fdwinfo[i].dacl.privtype = 0;
                               9784                 :             70 :         fdwinfo[i].dacl.initprivs = NULL;
  835                          9785                 :             70 :         fdwinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_fdwowner));
 4524 bruce@momjian.us         9786                 :             70 :         fdwinfo[i].fdwhandler = pg_strdup(PQgetvalue(res, i, i_fdwhandler));
                               9787                 :             70 :         fdwinfo[i].fdwvalidator = pg_strdup(PQgetvalue(res, i, i_fdwvalidator));
                               9788                 :             70 :         fdwinfo[i].fdwoptions = pg_strdup(PQgetvalue(res, i, i_fdwoptions));
                               9789                 :                : 
                               9790                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9791                 :             70 :         selectDumpableObject(&(fdwinfo[i].dobj), fout);
                               9792                 :                : 
                               9793                 :                :         /* Mark whether FDW has an ACL */
  860 tgl@sss.pgh.pa.us        9794         [ +  + ]:             70 :         if (!PQgetisnull(res, i, i_fdwacl))
                               9795                 :             46 :             fdwinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               9796                 :                :     }
                               9797                 :                : 
 5595 peter_e@gmx.net          9798                 :            155 :     PQclear(res);
                               9799                 :                : 
                               9800                 :            155 :     destroyPQExpBuffer(query);
                               9801                 :                : 
                               9802                 :            155 :     return fdwinfo;
                               9803                 :                : }
                               9804                 :                : 
                               9805                 :                : /*
                               9806                 :                :  * getForeignServers:
                               9807                 :                :  *    read all foreign servers in the system catalogs and return
                               9808                 :                :  *    them in the ForeignServerInfo * structure
                               9809                 :                :  *
                               9810                 :                :  *  numForeignServers is set to the number of servers read in
                               9811                 :                :  */
                               9812                 :                : ForeignServerInfo *
 4451 rhaas@postgresql.org     9813                 :            155 : getForeignServers(Archive *fout, int *numForeignServers)
                               9814                 :                : {
                               9815                 :                :     PGresult   *res;
                               9816                 :                :     int         ntups;
                               9817                 :                :     int         i;
                               9818                 :                :     PQExpBuffer query;
                               9819                 :                :     ForeignServerInfo *srvinfo;
                               9820                 :                :     int         i_tableoid;
                               9821                 :                :     int         i_oid;
                               9822                 :                :     int         i_srvname;
                               9823                 :                :     int         i_srvowner;
                               9824                 :                :     int         i_srvfdw;
                               9825                 :                :     int         i_srvtype;
                               9826                 :                :     int         i_srvversion;
                               9827                 :                :     int         i_srvacl;
                               9828                 :                :     int         i_acldefault;
                               9829                 :                :     int         i_srvoptions;
                               9830                 :                : 
 3718 sfrost@snowman.net       9831                 :            155 :     query = createPQExpBuffer();
                               9832                 :                : 
  586 drowley@postgresql.o     9833                 :            155 :     appendPQExpBufferStr(query, "SELECT tableoid, oid, srvname, "
                               9834                 :                :                          "srvowner, "
                               9835                 :                :                          "srvfdw, srvtype, srvversion, srvacl, "
                               9836                 :                :                          "acldefault('S', srvowner) AS acldefault, "
                               9837                 :                :                          "array_to_string(ARRAY("
                               9838                 :                :                          "SELECT quote_ident(option_name) || ' ' || "
                               9839                 :                :                          "quote_literal(option_value) "
                               9840                 :                :                          "FROM pg_options_to_table(srvoptions) "
                               9841                 :                :                          "ORDER BY option_name"
                               9842                 :                :                          "), E',\n    ') AS srvoptions "
                               9843                 :                :                          "FROM pg_foreign_server");
                               9844                 :                : 
 4450 rhaas@postgresql.org     9845                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9846                 :                : 
 5595 peter_e@gmx.net          9847                 :            155 :     ntups = PQntuples(res);
                               9848                 :            155 :     *numForeignServers = ntups;
                               9849                 :                : 
 4524 bruce@momjian.us         9850                 :            155 :     srvinfo = (ForeignServerInfo *) pg_malloc(ntups * sizeof(ForeignServerInfo));
                               9851                 :                : 
 4952 heikki.linnakangas@i     9852                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
 5595 peter_e@gmx.net          9853                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9854                 :            155 :     i_srvname = PQfnumber(res, "srvname");
  835 tgl@sss.pgh.pa.us        9855                 :            155 :     i_srvowner = PQfnumber(res, "srvowner");
 5595 peter_e@gmx.net          9856                 :            155 :     i_srvfdw = PQfnumber(res, "srvfdw");
                               9857                 :            155 :     i_srvtype = PQfnumber(res, "srvtype");
                               9858                 :            155 :     i_srvversion = PQfnumber(res, "srvversion");
                               9859                 :            155 :     i_srvacl = PQfnumber(res, "srvacl");
  860 tgl@sss.pgh.pa.us        9860                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
 5595 peter_e@gmx.net          9861                 :            155 :     i_srvoptions = PQfnumber(res, "srvoptions");
                               9862                 :                : 
                               9863         [ +  + ]:            229 :     for (i = 0; i < ntups; i++)
                               9864                 :                :     {
                               9865                 :             74 :         srvinfo[i].dobj.objType = DO_FOREIGN_SERVER;
 4952 heikki.linnakangas@i     9866                 :             74 :         srvinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
 5595 peter_e@gmx.net          9867                 :             74 :         srvinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9868                 :             74 :         AssignDumpId(&srvinfo[i].dobj);
 4524 bruce@momjian.us         9869                 :             74 :         srvinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_srvname));
 5595 peter_e@gmx.net          9870                 :             74 :         srvinfo[i].dobj.namespace = NULL;
  860 tgl@sss.pgh.pa.us        9871                 :             74 :         srvinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_srvacl));
                               9872                 :             74 :         srvinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               9873                 :             74 :         srvinfo[i].dacl.privtype = 0;
                               9874                 :             74 :         srvinfo[i].dacl.initprivs = NULL;
  835                          9875                 :             74 :         srvinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_srvowner));
 5595 peter_e@gmx.net          9876                 :             74 :         srvinfo[i].srvfdw = atooid(PQgetvalue(res, i, i_srvfdw));
 4524 bruce@momjian.us         9877                 :             74 :         srvinfo[i].srvtype = pg_strdup(PQgetvalue(res, i, i_srvtype));
                               9878                 :             74 :         srvinfo[i].srvversion = pg_strdup(PQgetvalue(res, i, i_srvversion));
                               9879                 :             74 :         srvinfo[i].srvoptions = pg_strdup(PQgetvalue(res, i, i_srvoptions));
                               9880                 :                : 
                               9881                 :                :         /* Decide whether we want to dump it */
 2930 sfrost@snowman.net       9882                 :             74 :         selectDumpableObject(&(srvinfo[i].dobj), fout);
                               9883                 :                : 
                               9884                 :                :         /* Servers have user mappings */
  860 tgl@sss.pgh.pa.us        9885                 :             74 :         srvinfo[i].dobj.components |= DUMP_COMPONENT_USERMAP;
                               9886                 :                : 
                               9887                 :                :         /* Mark whether server has an ACL */
                               9888         [ +  + ]:             74 :         if (!PQgetisnull(res, i, i_srvacl))
                               9889                 :             46 :             srvinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               9890                 :                :     }
                               9891                 :                : 
 5595 peter_e@gmx.net          9892                 :            155 :     PQclear(res);
                               9893                 :                : 
                               9894                 :            155 :     destroyPQExpBuffer(query);
                               9895                 :                : 
                               9896                 :            155 :     return srvinfo;
                               9897                 :                : }
                               9898                 :                : 
                               9899                 :                : /*
                               9900                 :                :  * getDefaultACLs:
                               9901                 :                :  *    read all default ACL information in the system catalogs and return
                               9902                 :                :  *    them in the DefaultACLInfo structure
                               9903                 :                :  *
                               9904                 :                :  *  numDefaultACLs is set to the number of ACLs read in
                               9905                 :                :  */
                               9906                 :                : DefaultACLInfo *
 3014 tgl@sss.pgh.pa.us        9907                 :            155 : getDefaultACLs(Archive *fout, int *numDefaultACLs)
                               9908                 :                : {
                               9909                 :            155 :     DumpOptions *dopt = fout->dopt;
                               9910                 :                :     DefaultACLInfo *daclinfo;
                               9911                 :                :     PQExpBuffer query;
                               9912                 :                :     PGresult   *res;
                               9913                 :                :     int         i_oid;
                               9914                 :                :     int         i_tableoid;
                               9915                 :                :     int         i_defaclrole;
                               9916                 :                :     int         i_defaclnamespace;
                               9917                 :                :     int         i_defaclobjtype;
                               9918                 :                :     int         i_defaclacl;
                               9919                 :                :     int         i_acldefault;
                               9920                 :                :     int         i,
                               9921                 :                :                 ntups;
                               9922                 :                : 
 5305                          9923                 :            155 :     query = createPQExpBuffer();
                               9924                 :                : 
                               9925                 :                :     /*
                               9926                 :                :      * Global entries (with defaclnamespace=0) replace the hard-wired default
                               9927                 :                :      * ACL for their object type.  We should dump them as deltas from the
                               9928                 :                :      * default ACL, since that will be used as a starting point for
                               9929                 :                :      * interpreting the ALTER DEFAULT PRIVILEGES commands.  On the other hand,
                               9930                 :                :      * non-global entries can only add privileges not revoke them.  We must
                               9931                 :                :      * dump those as-is (i.e., as deltas from an empty ACL).
                               9932                 :                :      *
                               9933                 :                :      * We can use defaclobjtype as the object type for acldefault(), except
                               9934                 :                :      * for the case of 'S' (DEFACLOBJ_SEQUENCE) which must be converted to
                               9935                 :                :      * 's'.
                               9936                 :                :      */
  586 drowley@postgresql.o     9937                 :            155 :     appendPQExpBufferStr(query,
                               9938                 :                :                          "SELECT oid, tableoid, "
                               9939                 :                :                          "defaclrole, "
                               9940                 :                :                          "defaclnamespace, "
                               9941                 :                :                          "defaclobjtype, "
                               9942                 :                :                          "defaclacl, "
                               9943                 :                :                          "CASE WHEN defaclnamespace = 0 THEN "
                               9944                 :                :                          "acldefault(CASE WHEN defaclobjtype = 'S' "
                               9945                 :                :                          "THEN 's'::\"char\" ELSE defaclobjtype END, "
                               9946                 :                :                          "defaclrole) ELSE '{}' END AS acldefault "
                               9947                 :                :                          "FROM pg_default_acl");
                               9948                 :                : 
 4450 rhaas@postgresql.org     9949                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                               9950                 :                : 
 5305 tgl@sss.pgh.pa.us        9951                 :            155 :     ntups = PQntuples(res);
                               9952                 :            155 :     *numDefaultACLs = ntups;
                               9953                 :                : 
 4524 bruce@momjian.us         9954                 :            155 :     daclinfo = (DefaultACLInfo *) pg_malloc(ntups * sizeof(DefaultACLInfo));
                               9955                 :                : 
 5305 tgl@sss.pgh.pa.us        9956                 :            155 :     i_oid = PQfnumber(res, "oid");
                               9957                 :            155 :     i_tableoid = PQfnumber(res, "tableoid");
                               9958                 :            155 :     i_defaclrole = PQfnumber(res, "defaclrole");
                               9959                 :            155 :     i_defaclnamespace = PQfnumber(res, "defaclnamespace");
                               9960                 :            155 :     i_defaclobjtype = PQfnumber(res, "defaclobjtype");
                               9961                 :            155 :     i_defaclacl = PQfnumber(res, "defaclacl");
  860                          9962                 :            155 :     i_acldefault = PQfnumber(res, "acldefault");
                               9963                 :                : 
 5305                          9964         [ +  + ]:            339 :     for (i = 0; i < ntups; i++)
                               9965                 :                :     {
 5161 bruce@momjian.us         9966                 :            184 :         Oid         nspid = atooid(PQgetvalue(res, i, i_defaclnamespace));
                               9967                 :                : 
 5305 tgl@sss.pgh.pa.us        9968                 :            184 :         daclinfo[i].dobj.objType = DO_DEFAULT_ACL;
                               9969                 :            184 :         daclinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
                               9970                 :            184 :         daclinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                               9971                 :            184 :         AssignDumpId(&daclinfo[i].dobj);
                               9972                 :                :         /* cheesy ... is it worth coming up with a better object name? */
 4524 bruce@momjian.us         9973                 :            184 :         daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
                               9974                 :                : 
 5305 tgl@sss.pgh.pa.us        9975         [ +  + ]:            184 :         if (nspid != InvalidOid)
 1328 peter@eisentraut.org     9976                 :             92 :             daclinfo[i].dobj.namespace = findNamespace(nspid);
                               9977                 :                :         else
 5305 tgl@sss.pgh.pa.us        9978                 :             92 :             daclinfo[i].dobj.namespace = NULL;
                               9979                 :                : 
  860                          9980                 :            184 :         daclinfo[i].dacl.acl = pg_strdup(PQgetvalue(res, i, i_defaclacl));
                               9981                 :            184 :         daclinfo[i].dacl.acldefault = pg_strdup(PQgetvalue(res, i, i_acldefault));
                               9982                 :            184 :         daclinfo[i].dacl.privtype = 0;
                               9983                 :            184 :         daclinfo[i].dacl.initprivs = NULL;
  835                          9984                 :            184 :         daclinfo[i].defaclrole = getRoleName(PQgetvalue(res, i, i_defaclrole));
 5305                          9985                 :            184 :         daclinfo[i].defaclobjtype = *(PQgetvalue(res, i, i_defaclobjtype));
                               9986                 :                : 
                               9987                 :                :         /* Default ACLs are ACLs, of course */
  860                          9988                 :            184 :         daclinfo[i].dobj.components |= DUMP_COMPONENT_ACL;
                               9989                 :                : 
                               9990                 :                :         /* Decide whether we want to dump it */
 3014                          9991                 :            184 :         selectDumpableDefaultACL(&(daclinfo[i]), dopt);
                               9992                 :                :     }
                               9993                 :                : 
 5305                          9994                 :            155 :     PQclear(res);
                               9995                 :                : 
                               9996                 :            155 :     destroyPQExpBuffer(query);
                               9997                 :                : 
                               9998                 :            155 :     return daclinfo;
                               9999                 :                : }
                              10000                 :                : 
                              10001                 :                : /*
                              10002                 :                :  * getRoleName -- look up the name of a role, given its OID
                              10003                 :                :  *
                              10004                 :                :  * In current usage, we don't expect failures, so error out for a bad OID.
                              10005                 :                :  */
                              10006                 :                : static const char *
  835                         10007                 :         584639 : getRoleName(const char *roleoid_str)
                              10008                 :                : {
                              10009                 :         584639 :     Oid         roleoid = atooid(roleoid_str);
                              10010                 :                : 
                              10011                 :                :     /*
                              10012                 :                :      * Do binary search to find the appropriate item.
                              10013                 :                :      */
                              10014         [ +  - ]:         584639 :     if (nrolenames > 0)
                              10015                 :                :     {
                              10016                 :         584639 :         RoleNameItem *low = &rolenames[0];
                              10017                 :         584639 :         RoleNameItem *high = &rolenames[nrolenames - 1];
                              10018                 :                : 
                              10019         [ +  - ]:        2338626 :         while (low <= high)
                              10020                 :                :         {
                              10021                 :        2338626 :             RoleNameItem *middle = low + (high - low) / 2;
                              10022                 :                : 
                              10023         [ +  + ]:        2338626 :             if (roleoid < middle->roleoid)
                              10024                 :        1752766 :                 high = middle - 1;
                              10025         [ +  + ]:         585860 :             else if (roleoid > middle->roleoid)
                              10026                 :           1221 :                 low = middle + 1;
                              10027                 :                :             else
                              10028                 :         584639 :                 return middle->rolename; /* found a match */
                              10029                 :                :         }
                              10030                 :                :     }
                              10031                 :                : 
  737 tgl@sss.pgh.pa.us       10032                 :UBC           0 :     pg_fatal("role with OID %u does not exist", roleoid);
                              10033                 :                :     return NULL;                /* keep compiler quiet */
                              10034                 :                : }
                              10035                 :                : 
                              10036                 :                : /*
                              10037                 :                :  * collectRoleNames --
                              10038                 :                :  *
                              10039                 :                :  * Construct a table of all known roles.
                              10040                 :                :  * The table is sorted by OID for speed in lookup.
                              10041                 :                :  */
                              10042                 :                : static void
  835 tgl@sss.pgh.pa.us       10043                 :CBC         156 : collectRoleNames(Archive *fout)
                              10044                 :                : {
                              10045                 :                :     PGresult   *res;
                              10046                 :                :     const char *query;
                              10047                 :                :     int         i;
                              10048                 :                : 
                              10049                 :            156 :     query = "SELECT oid, rolname FROM pg_catalog.pg_roles ORDER BY 1";
                              10050                 :                : 
                              10051                 :            156 :     res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
                              10052                 :                : 
                              10053                 :            156 :     nrolenames = PQntuples(res);
                              10054                 :                : 
                              10055                 :            156 :     rolenames = (RoleNameItem *) pg_malloc(nrolenames * sizeof(RoleNameItem));
                              10056                 :                : 
                              10057         [ +  + ]:           2858 :     for (i = 0; i < nrolenames; i++)
                              10058                 :                :     {
                              10059                 :           2702 :         rolenames[i].roleoid = atooid(PQgetvalue(res, i, 0));
                              10060                 :           2702 :         rolenames[i].rolename = pg_strdup(PQgetvalue(res, i, 1));
                              10061                 :                :     }
                              10062                 :                : 
                              10063                 :            156 :     PQclear(res);
                              10064                 :            156 : }
                              10065                 :                : 
                              10066                 :                : /*
                              10067                 :                :  * getAdditionalACLs
                              10068                 :                :  *
                              10069                 :                :  * We have now created all the DumpableObjects, and collected the ACL data
                              10070                 :                :  * that appears in the directly-associated catalog entries.  However, there's
                              10071                 :                :  * more ACL-related info to collect.  If any of a table's columns have ACLs,
                              10072                 :                :  * we must set the TableInfo's DUMP_COMPONENT_ACL components flag, as well as
                              10073                 :                :  * its hascolumnACLs flag (we won't store the ACLs themselves here, though).
                              10074                 :                :  * Also, in versions having the pg_init_privs catalog, read that and load the
                              10075                 :                :  * information into the relevant DumpableObjects.
                              10076                 :                :  */
                              10077                 :                : static void
  860                         10078                 :            153 : getAdditionalACLs(Archive *fout)
                              10079                 :                : {
                              10080                 :            153 :     PQExpBuffer query = createPQExpBuffer();
                              10081                 :                :     PGresult   *res;
                              10082                 :                :     int         ntups,
                              10083                 :                :                 i;
                              10084                 :                : 
                              10085                 :                :     /* Check for per-column ACLs */
  852                         10086                 :            153 :     appendPQExpBufferStr(query,
                              10087                 :                :                          "SELECT DISTINCT attrelid FROM pg_attribute "
                              10088                 :                :                          "WHERE attacl IS NOT NULL");
                              10089                 :                : 
                              10090                 :            153 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10091                 :                : 
                              10092                 :            153 :     ntups = PQntuples(res);
                              10093         [ +  + ]:            475 :     for (i = 0; i < ntups; i++)
                              10094                 :                :     {
                              10095                 :            322 :         Oid         relid = atooid(PQgetvalue(res, i, 0));
                              10096                 :                :         TableInfo  *tblinfo;
                              10097                 :                : 
                              10098                 :            322 :         tblinfo = findTableByOid(relid);
                              10099                 :                :         /* OK to ignore tables we haven't got a DumpableObject for */
                              10100         [ +  - ]:            322 :         if (tblinfo)
                              10101                 :                :         {
                              10102                 :            322 :             tblinfo->dobj.components |= DUMP_COMPONENT_ACL;
                              10103                 :            322 :             tblinfo->hascolumnACLs = true;
                              10104                 :                :         }
                              10105                 :                :     }
                              10106                 :            153 :     PQclear(res);
                              10107                 :                : 
                              10108                 :                :     /* Fetch initial-privileges data */
  860                         10109         [ +  - ]:            153 :     if (fout->remoteVersion >= 90600)
                              10110                 :                :     {
                              10111                 :            153 :         printfPQExpBuffer(query,
                              10112                 :                :                           "SELECT objoid, classoid, objsubid, privtype, initprivs "
                              10113                 :                :                           "FROM pg_init_privs");
                              10114                 :                : 
                              10115                 :            153 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10116                 :                : 
                              10117                 :            153 :         ntups = PQntuples(res);
                              10118         [ +  + ]:          34580 :         for (i = 0; i < ntups; i++)
                              10119                 :                :         {
                              10120                 :          34427 :             Oid         objoid = atooid(PQgetvalue(res, i, 0));
                              10121                 :          34427 :             Oid         classoid = atooid(PQgetvalue(res, i, 1));
                              10122                 :          34427 :             int         objsubid = atoi(PQgetvalue(res, i, 2));
                              10123                 :          34427 :             char        privtype = *(PQgetvalue(res, i, 3));
                              10124                 :          34427 :             char       *initprivs = PQgetvalue(res, i, 4);
                              10125                 :                :             CatalogId   objId;
                              10126                 :                :             DumpableObject *dobj;
                              10127                 :                : 
                              10128                 :          34427 :             objId.tableoid = classoid;
                              10129                 :          34427 :             objId.oid = objoid;
                              10130                 :          34427 :             dobj = findObjectByCatalogId(objId);
                              10131                 :                :             /* OK to ignore entries we haven't got a DumpableObject for */
                              10132         [ +  + ]:          34427 :             if (dobj)
                              10133                 :                :             {
                              10134                 :                :                 /* Cope with sub-object initprivs */
                              10135         [ +  + ]:          24986 :                 if (objsubid != 0)
                              10136                 :                :                 {
                              10137         [ +  - ]:           2625 :                     if (dobj->objType == DO_TABLE)
                              10138                 :                :                     {
                              10139                 :                :                         /* For a column initprivs, set the table's ACL flags */
                              10140                 :           2625 :                         dobj->components |= DUMP_COMPONENT_ACL;
                              10141                 :           2625 :                         ((TableInfo *) dobj)->hascolumnACLs = true;
                              10142                 :                :                     }
                              10143                 :                :                     else
  860 tgl@sss.pgh.pa.us       10144                 :UBC           0 :                         pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10145                 :                :                                        classoid, objoid, objsubid);
  860 tgl@sss.pgh.pa.us       10146                 :CBC        2774 :                     continue;
                              10147                 :                :                 }
                              10148                 :                : 
                              10149                 :                :                 /*
                              10150                 :                :                  * We ignore any pg_init_privs.initprivs entry for the public
                              10151                 :                :                  * schema, as explained in getNamespaces().
                              10152                 :                :                  */
                              10153         [ +  + ]:          22361 :                 if (dobj->objType == DO_NAMESPACE &&
                              10154         [ +  + ]:            302 :                     strcmp(dobj->name, "public") == 0)
                              10155                 :            149 :                     continue;
                              10156                 :                : 
                              10157                 :                :                 /* Else it had better be of a type we think has ACLs */
                              10158         [ +  + ]:          22212 :                 if (dobj->objType == DO_NAMESPACE ||
                              10159         [ +  + ]:          22059 :                     dobj->objType == DO_TYPE ||
                              10160         [ +  + ]:          22035 :                     dobj->objType == DO_FUNC ||
                              10161         [ +  + ]:          21942 :                     dobj->objType == DO_AGG ||
                              10162         [ -  + ]:          21918 :                     dobj->objType == DO_TABLE ||
  860 tgl@sss.pgh.pa.us       10163         [ #  # ]:UBC           0 :                     dobj->objType == DO_PROCLANG ||
                              10164         [ #  # ]:              0 :                     dobj->objType == DO_FDW ||
                              10165         [ #  # ]:              0 :                     dobj->objType == DO_FOREIGN_SERVER)
  860 tgl@sss.pgh.pa.us       10166                 :CBC       22212 :                 {
                              10167                 :          22212 :                     DumpableObjectWithAcl *daobj = (DumpableObjectWithAcl *) dobj;
                              10168                 :                : 
                              10169                 :          22212 :                     daobj->dacl.privtype = privtype;
                              10170                 :          22212 :                     daobj->dacl.initprivs = pstrdup(initprivs);
                              10171                 :                :                 }
                              10172                 :                :                 else
  860 tgl@sss.pgh.pa.us       10173                 :UBC           0 :                     pg_log_warning("unsupported pg_init_privs entry: %u %u %d",
                              10174                 :                :                                    classoid, objoid, objsubid);
                              10175                 :                :             }
                              10176                 :                :         }
  860 tgl@sss.pgh.pa.us       10177                 :CBC         153 :         PQclear(res);
                              10178                 :                :     }
                              10179                 :                : 
                              10180                 :            153 :     destroyPQExpBuffer(query);
                              10181                 :            153 : }
                              10182                 :                : 
                              10183                 :                : /*
                              10184                 :                :  * dumpCommentExtended --
                              10185                 :                :  *
                              10186                 :                :  * This routine is used to dump any comments associated with the
                              10187                 :                :  * object handed to this routine. The routine takes the object type
                              10188                 :                :  * and object name (ready to print, except for schema decoration), plus
                              10189                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              10190                 :                :  * plus catalog ID and subid which are the lookup key for pg_description,
                              10191                 :                :  * plus the dump ID for the object (for setting a dependency).
                              10192                 :                :  * If a matching pg_description entry is found, it is dumped.
                              10193                 :                :  *
                              10194                 :                :  * Note: in some cases, such as comments for triggers and rules, the "type"
                              10195                 :                :  * string really looks like, e.g., "TRIGGER name ON".  This is a bit of a hack
                              10196                 :                :  * but it doesn't seem worth complicating the API for all callers to make
                              10197                 :                :  * it cleaner.
                              10198                 :                :  *
                              10199                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              10200                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              10201                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              10202                 :                :  * ordering of the comment in the dump file, because this routine is called
                              10203                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              10204                 :                :  * calling ArchiveEntry() for the specified object.
                              10205                 :                :  */
                              10206                 :                : static void
 1021 noah@leadboat.com       10207                 :           2646 : dumpCommentExtended(Archive *fout, const char *type,
                              10208                 :                :                     const char *name, const char *namespace,
                              10209                 :                :                     const char *owner, CatalogId catalogId,
                              10210                 :                :                     int subid, DumpId dumpId,
                              10211                 :                :                     const char *initdb_comment)
                              10212                 :                : {
 3014 tgl@sss.pgh.pa.us       10213                 :           2646 :     DumpOptions *dopt = fout->dopt;
                              10214                 :                :     CommentItem *comments;
                              10215                 :                :     int         ncomments;
                              10216                 :                : 
                              10217                 :                :     /* do nothing, if --no-comments is supplied */
 2271                         10218         [ -  + ]:           2646 :     if (dopt->no_comments)
 2271 tgl@sss.pgh.pa.us       10219                 :UBC           0 :         return;
                              10220                 :                : 
                              10221                 :                :     /* Comments are schema not data ... except LO comments are data */
 2239 tgl@sss.pgh.pa.us       10222         [ +  + ]:CBC        2646 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              10223                 :                :     {
 3470 alvherre@alvh.no-ip.    10224         [ -  + ]:           2594 :         if (dopt->dataOnly)
 5169 tgl@sss.pgh.pa.us       10225                 :UBC           0 :             return;
                              10226                 :                :     }
                              10227                 :                :     else
                              10228                 :                :     {
                              10229                 :                :         /* We do dump LO comments in binary-upgrade mode */
 2596 sfrost@snowman.net      10230   [ +  +  -  + ]:CBC          52 :         if (dopt->schemaOnly && !dopt->binary_upgrade)
 5169 tgl@sss.pgh.pa.us       10231                 :UBC           0 :             return;
                              10232                 :                :     }
                              10233                 :                : 
                              10234                 :                :     /* Search for comments associated with catalogId, using table */
  836 tgl@sss.pgh.pa.us       10235                 :CBC        2646 :     ncomments = findComments(catalogId.tableoid, catalogId.oid,
                              10236                 :                :                              &comments);
                              10237                 :                : 
                              10238                 :                :     /* Is there one matching the subid? */
 7330                         10239         [ +  + ]:           2646 :     while (ncomments > 0)
                              10240                 :                :     {
                              10241         [ +  - ]:           2601 :         if (comments->objsubid == subid)
                              10242                 :           2601 :             break;
 7330 tgl@sss.pgh.pa.us       10243                 :UBC           0 :         comments++;
                              10244                 :              0 :         ncomments--;
                              10245                 :                :     }
                              10246                 :                : 
 1021 noah@leadboat.com       10247         [ +  + ]:CBC        2646 :     if (initdb_comment != NULL)
                              10248                 :                :     {
                              10249                 :                :         static CommentItem empty_comment = {.descr = ""};
                              10250                 :                : 
                              10251                 :                :         /*
                              10252                 :                :          * initdb creates this object with a comment.  Skip dumping the
                              10253                 :                :          * initdb-provided comment, which would complicate matters for
                              10254                 :                :          * non-superuser use of pg_dump.  When the DBA has removed initdb's
                              10255                 :                :          * comment, replicate that.
                              10256                 :                :          */
                              10257         [ +  + ]:            113 :         if (ncomments == 0)
                              10258                 :                :         {
                              10259                 :              4 :             comments = &empty_comment;
                              10260                 :              4 :             ncomments = 1;
                              10261                 :                :         }
                              10262         [ +  - ]:            109 :         else if (strcmp(comments->descr, initdb_comment) == 0)
                              10263                 :            109 :             ncomments = 0;
                              10264                 :                :     }
                              10265                 :                : 
                              10266                 :                :     /* If a comment exists, build COMMENT ON statement */
 7330 tgl@sss.pgh.pa.us       10267         [ +  + ]:           2646 :     if (ncomments > 0)
                              10268                 :                :     {
                              10269                 :           2496 :         PQExpBuffer query = createPQExpBuffer();
 2239                         10270                 :           2496 :         PQExpBuffer tag = createPQExpBuffer();
                              10271                 :                : 
                              10272                 :           2496 :         appendPQExpBuffer(query, "COMMENT ON %s ", type);
                              10273   [ +  +  +  - ]:           2496 :         if (namespace && *namespace)
                              10274                 :           2342 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
                              10275                 :           2496 :         appendPQExpBuffer(query, "%s IS ", name);
 6531                         10276                 :           2496 :         appendStringLiteralAH(query, comments->descr, fout);
 3800 heikki.linnakangas@i    10277                 :           2496 :         appendPQExpBufferStr(query, ";\n");
                              10278                 :                : 
 2239 tgl@sss.pgh.pa.us       10279                 :           2496 :         appendPQExpBuffer(tag, "%s %s", type, name);
                              10280                 :                : 
                              10281                 :                :         /*
                              10282                 :                :          * We mark comments as SECTION_NONE because they really belong in the
                              10283                 :                :          * same section as their parent, whether that is pre-data or
                              10284                 :                :          * post-data.
                              10285                 :                :          */
 7435                         10286                 :           2496 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    10287                 :           2496 :                      ARCHIVE_OPTS(.tag = tag->data,
                              10288                 :                :                                   .namespace = namespace,
                              10289                 :                :                                   .owner = owner,
                              10290                 :                :                                   .description = "COMMENT",
                              10291                 :                :                                   .section = SECTION_NONE,
                              10292                 :                :                                   .createStmt = query->data,
                              10293                 :                :                                   .deps = &dumpId,
                              10294                 :                :                                   .nDeps = 1));
                              10295                 :                : 
 7330 tgl@sss.pgh.pa.us       10296                 :           2496 :         destroyPQExpBuffer(query);
 2239                         10297                 :           2496 :         destroyPQExpBuffer(tag);
                              10298                 :                :     }
                              10299                 :                : }
                              10300                 :                : 
                              10301                 :                : /*
                              10302                 :                :  * dumpComment --
                              10303                 :                :  *
                              10304                 :                :  * Typical simplification of the above function.
                              10305                 :                :  */
                              10306                 :                : static inline void
 1021 noah@leadboat.com       10307                 :           2518 : dumpComment(Archive *fout, const char *type,
                              10308                 :                :             const char *name, const char *namespace,
                              10309                 :                :             const char *owner, CatalogId catalogId,
                              10310                 :                :             int subid, DumpId dumpId)
                              10311                 :                : {
                              10312                 :           2518 :     dumpCommentExtended(fout, type, name, namespace, owner,
                              10313                 :                :                         catalogId, subid, dumpId, NULL);
                              10314                 :           2518 : }
                              10315                 :                : 
                              10316                 :                : /*
                              10317                 :                :  * dumpTableComment --
                              10318                 :                :  *
                              10319                 :                :  * As above, but dump comments for both the specified table (or view)
                              10320                 :                :  * and its columns.
                              10321                 :                :  */
                              10322                 :                : static void
 1159 peter@eisentraut.org    10323                 :             82 : dumpTableComment(Archive *fout, const TableInfo *tbinfo,
                              10324                 :                :                  const char *reltypename)
                              10325                 :                : {
 3014 tgl@sss.pgh.pa.us       10326                 :             82 :     DumpOptions *dopt = fout->dopt;
                              10327                 :                :     CommentItem *comments;
                              10328                 :                :     int         ncomments;
                              10329                 :                :     PQExpBuffer query;
                              10330                 :                :     PQExpBuffer tag;
                              10331                 :                : 
                              10332                 :                :     /* do nothing, if --no-comments is supplied */
 2271                         10333         [ -  + ]:             82 :     if (dopt->no_comments)
 2271 tgl@sss.pgh.pa.us       10334                 :UBC           0 :         return;
                              10335                 :                : 
                              10336                 :                :     /* Comments are SCHEMA not data */
 3470 alvherre@alvh.no-ip.    10337         [ -  + ]:CBC          82 :     if (dopt->dataOnly)
 8010 tgl@sss.pgh.pa.us       10338                 :UBC           0 :         return;
                              10339                 :                : 
                              10340                 :                :     /* Search for comments associated with relation, using table */
  836 tgl@sss.pgh.pa.us       10341                 :CBC          82 :     ncomments = findComments(tbinfo->dobj.catId.tableoid,
 7330                         10342                 :             82 :                              tbinfo->dobj.catId.oid,
                              10343                 :                :                              &comments);
                              10344                 :                : 
                              10345                 :                :     /* If comments exist, build COMMENT ON statements */
                              10346         [ -  + ]:             82 :     if (ncomments <= 0)
 7330 tgl@sss.pgh.pa.us       10347                 :UBC           0 :         return;
                              10348                 :                : 
 8010 tgl@sss.pgh.pa.us       10349                 :CBC          82 :     query = createPQExpBuffer();
 2239                         10350                 :             82 :     tag = createPQExpBuffer();
                              10351                 :                : 
 7330                         10352         [ +  + ]:            236 :     while (ncomments > 0)
                              10353                 :                :     {
                              10354                 :            154 :         const char *descr = comments->descr;
                              10355                 :            154 :         int         objsubid = comments->objsubid;
                              10356                 :                : 
 8010                         10357         [ +  + ]:            154 :         if (objsubid == 0)
                              10358                 :                :         {
 2239                         10359                 :             36 :             resetPQExpBuffer(tag);
                              10360                 :             36 :             appendPQExpBuffer(tag, "%s %s", reltypename,
 7347                         10361                 :             36 :                               fmtId(tbinfo->dobj.name));
                              10362                 :                : 
 8010                         10363                 :             36 :             resetPQExpBuffer(query);
 2239                         10364                 :             36 :             appendPQExpBuffer(query, "COMMENT ON %s %s IS ", reltypename,
                              10365                 :             36 :                               fmtQualifiedDumpable(tbinfo));
 6531                         10366                 :             36 :             appendStringLiteralAH(query, descr, fout);
 3800 heikki.linnakangas@i    10367                 :             36 :             appendPQExpBufferStr(query, ";\n");
                              10368                 :                : 
 7435 tgl@sss.pgh.pa.us       10369                 :             36 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    10370                 :             36 :                          ARCHIVE_OPTS(.tag = tag->data,
                              10371                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              10372                 :                :                                       .owner = tbinfo->rolname,
                              10373                 :                :                                       .description = "COMMENT",
                              10374                 :                :                                       .section = SECTION_NONE,
                              10375                 :                :                                       .createStmt = query->data,
                              10376                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              10377                 :                :                                       .nDeps = 1));
                              10378                 :                :         }
 8010 tgl@sss.pgh.pa.us       10379   [ +  -  +  - ]:            118 :         else if (objsubid > 0 && objsubid <= tbinfo->numatts)
                              10380                 :                :         {
 2239                         10381                 :            118 :             resetPQExpBuffer(tag);
                              10382                 :            118 :             appendPQExpBuffer(tag, "COLUMN %s.",
 7347                         10383                 :            118 :                               fmtId(tbinfo->dobj.name));
 2239                         10384                 :            118 :             appendPQExpBufferStr(tag, fmtId(tbinfo->attnames[objsubid - 1]));
                              10385                 :                : 
 8010                         10386                 :            118 :             resetPQExpBuffer(query);
 2239                         10387                 :            118 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              10388                 :            118 :                               fmtQualifiedDumpable(tbinfo));
                              10389                 :            118 :             appendPQExpBuffer(query, "%s IS ",
                              10390                 :            118 :                               fmtId(tbinfo->attnames[objsubid - 1]));
 6531                         10391                 :            118 :             appendStringLiteralAH(query, descr, fout);
 3800 heikki.linnakangas@i    10392                 :            118 :             appendPQExpBufferStr(query, ";\n");
                              10393                 :                : 
 7435 tgl@sss.pgh.pa.us       10394                 :            118 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    10395                 :            118 :                          ARCHIVE_OPTS(.tag = tag->data,
                              10396                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              10397                 :                :                                       .owner = tbinfo->rolname,
                              10398                 :                :                                       .description = "COMMENT",
                              10399                 :                :                                       .section = SECTION_NONE,
                              10400                 :                :                                       .createStmt = query->data,
                              10401                 :                :                                       .deps = &(tbinfo->dobj.dumpId),
                              10402                 :                :                                       .nDeps = 1));
                              10403                 :                :         }
                              10404                 :                : 
 7330 tgl@sss.pgh.pa.us       10405                 :            154 :         comments++;
                              10406                 :            154 :         ncomments--;
                              10407                 :                :     }
                              10408                 :                : 
 8290                         10409                 :             82 :     destroyPQExpBuffer(query);
 2239                         10410                 :             82 :     destroyPQExpBuffer(tag);
                              10411                 :                : }
                              10412                 :                : 
                              10413                 :                : /*
                              10414                 :                :  * findComments --
                              10415                 :                :  *
                              10416                 :                :  * Find the comment(s), if any, associated with the given object.  All the
                              10417                 :                :  * objsubid values associated with the given classoid/objoid are found with
                              10418                 :                :  * one search.
                              10419                 :                :  */
                              10420                 :                : static int
  836                         10421                 :           2764 : findComments(Oid classoid, Oid objoid, CommentItem **items)
                              10422                 :                : {
 7330                         10423                 :           2764 :     CommentItem *middle = NULL;
                              10424                 :                :     CommentItem *low;
                              10425                 :                :     CommentItem *high;
                              10426                 :                :     int         nmatch;
                              10427                 :                : 
                              10428                 :                :     /*
                              10429                 :                :      * Do binary search to find some item matching the object.
                              10430                 :                :      */
                              10431                 :           2764 :     low = &comments[0];
 7168 bruce@momjian.us        10432                 :           2764 :     high = &comments[ncomments - 1];
 7330 tgl@sss.pgh.pa.us       10433         [ +  + ]:          27503 :     while (low <= high)
                              10434                 :                :     {
                              10435                 :          27458 :         middle = low + (high - low) / 2;
                              10436                 :                : 
                              10437         [ +  + ]:          27458 :         if (classoid < middle->classoid)
                              10438                 :           4937 :             high = middle - 1;
                              10439         [ +  + ]:          22521 :         else if (classoid > middle->classoid)
                              10440                 :           3867 :             low = middle + 1;
                              10441         [ +  + ]:          18654 :         else if (objoid < middle->objoid)
                              10442                 :           7201 :             high = middle - 1;
                              10443         [ +  + ]:          11453 :         else if (objoid > middle->objoid)
                              10444                 :           8734 :             low = middle + 1;
                              10445                 :                :         else
                              10446                 :           2719 :             break;              /* found a match */
                              10447                 :                :     }
                              10448                 :                : 
                              10449         [ +  + ]:           2764 :     if (low > high)              /* no matches */
                              10450                 :                :     {
                              10451                 :             45 :         *items = NULL;
                              10452                 :             45 :         return 0;
                              10453                 :                :     }
                              10454                 :                : 
                              10455                 :                :     /*
                              10456                 :                :      * Now determine how many items match the object.  The search loop
                              10457                 :                :      * invariant still holds: only items between low and high inclusive could
                              10458                 :                :      * match.
                              10459                 :                :      */
                              10460                 :           2719 :     nmatch = 1;
                              10461         [ +  + ]:           2791 :     while (middle > low)
                              10462                 :                :     {
                              10463         [ +  + ]:           1360 :         if (classoid != middle[-1].classoid ||
                              10464         [ +  + ]:           1246 :             objoid != middle[-1].objoid)
                              10465                 :                :             break;
 7330 tgl@sss.pgh.pa.us       10466                 :GBC          72 :         middle--;
                              10467                 :             72 :         nmatch++;
                              10468                 :                :     }
                              10469                 :                : 
 7330 tgl@sss.pgh.pa.us       10470                 :CBC        2719 :     *items = middle;
                              10471                 :                : 
                              10472                 :           2719 :     middle += nmatch;
                              10473         [ +  + ]:           2719 :     while (middle <= high)
                              10474                 :                :     {
                              10475         [ +  + ]:           1557 :         if (classoid != middle->classoid ||
                              10476         [ -  + ]:           1194 :             objoid != middle->objoid)
                              10477                 :                :             break;
 7330 tgl@sss.pgh.pa.us       10478                 :LBC        (72) :         middle++;
                              10479                 :           (72) :         nmatch++;
                              10480                 :                :     }
                              10481                 :                : 
 7330 tgl@sss.pgh.pa.us       10482                 :CBC        2719 :     return nmatch;
                              10483                 :                : }
                              10484                 :                : 
                              10485                 :                : /*
                              10486                 :                :  * collectComments --
                              10487                 :                :  *
                              10488                 :                :  * Construct a table of all comments available for database objects;
                              10489                 :                :  * also set the has-comment component flag for each relevant object.
                              10490                 :                :  *
                              10491                 :                :  * We used to do per-object queries for the comments, but it's much faster
                              10492                 :                :  * to pull them all over at once, and on most databases the memory cost
                              10493                 :                :  * isn't high.
                              10494                 :                :  *
                              10495                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              10496                 :                :  */
                              10497                 :                : static void
  860                         10498                 :            155 : collectComments(Archive *fout)
                              10499                 :                : {
                              10500                 :                :     PGresult   *res;
                              10501                 :                :     PQExpBuffer query;
                              10502                 :                :     int         i_description;
                              10503                 :                :     int         i_classoid;
                              10504                 :                :     int         i_objoid;
                              10505                 :                :     int         i_objsubid;
                              10506                 :                :     int         ntups;
                              10507                 :                :     int         i;
                              10508                 :                :     DumpableObject *dobj;
                              10509                 :                : 
 7330                         10510                 :            155 :     query = createPQExpBuffer();
                              10511                 :                : 
 2741                         10512                 :            155 :     appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
                              10513                 :                :                          "FROM pg_catalog.pg_description "
                              10514                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              10515                 :                : 
 4450 rhaas@postgresql.org    10516                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              10517                 :                : 
                              10518                 :                :     /* Construct lookup table containing OIDs in numeric form */
                              10519                 :                : 
 7330 tgl@sss.pgh.pa.us       10520                 :            155 :     i_description = PQfnumber(res, "description");
                              10521                 :            155 :     i_classoid = PQfnumber(res, "classoid");
                              10522                 :            155 :     i_objoid = PQfnumber(res, "objoid");
                              10523                 :            155 :     i_objsubid = PQfnumber(res, "objsubid");
                              10524                 :                : 
                              10525                 :            155 :     ntups = PQntuples(res);
                              10526                 :                : 
 4524 bruce@momjian.us        10527                 :            155 :     comments = (CommentItem *) pg_malloc(ntups * sizeof(CommentItem));
  860 tgl@sss.pgh.pa.us       10528                 :            155 :     ncomments = 0;
                              10529                 :            155 :     dobj = NULL;
                              10530                 :                : 
 7330                         10531         [ +  + ]:         811341 :     for (i = 0; i < ntups; i++)
                              10532                 :                :     {
                              10533                 :                :         CatalogId   objId;
                              10534                 :                :         int         subid;
                              10535                 :                : 
  860                         10536                 :         811186 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              10537                 :         811186 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              10538                 :         811186 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              10539                 :                : 
                              10540                 :                :         /* We needn't remember comments that don't match any dumpable object */
                              10541         [ +  + ]:         811186 :         if (dobj == NULL ||
                              10542         [ +  + ]:         296953 :             dobj->catId.tableoid != objId.tableoid ||
                              10543         [ +  + ]:         295012 :             dobj->catId.oid != objId.oid)
                              10544                 :         811094 :             dobj = findObjectByCatalogId(objId);
                              10545         [ +  + ]:         811186 :         if (dobj == NULL)
                              10546                 :         514082 :             continue;
                              10547                 :                : 
                              10548                 :                :         /*
                              10549                 :                :          * Comments on columns of composite types are linked to the type's
                              10550                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_COMMENT flag
                              10551                 :                :          * in the type's own DumpableObject.
                              10552                 :                :          */
                              10553   [ +  +  +  - ]:         297104 :         if (subid != 0 && dobj->objType == DO_TABLE &&
                              10554         [ +  + ]:            194 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              10555                 :             46 :         {
                              10556                 :                :             TypeInfo   *cTypeInfo;
                              10557                 :                : 
                              10558                 :             46 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              10559         [ +  - ]:             46 :             if (cTypeInfo)
                              10560                 :             46 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_COMMENT;
                              10561                 :                :         }
                              10562                 :                :         else
                              10563                 :         297058 :             dobj->components |= DUMP_COMPONENT_COMMENT;
                              10564                 :                : 
                              10565                 :         297104 :         comments[ncomments].descr = pg_strdup(PQgetvalue(res, i, i_description));
                              10566                 :         297104 :         comments[ncomments].classoid = objId.tableoid;
                              10567                 :         297104 :         comments[ncomments].objoid = objId.oid;
                              10568                 :         297104 :         comments[ncomments].objsubid = subid;
                              10569                 :         297104 :         ncomments++;
                              10570                 :                :     }
                              10571                 :                : 
                              10572                 :            155 :     PQclear(res);
 7330                         10573                 :            155 :     destroyPQExpBuffer(query);
                              10574                 :            155 : }
                              10575                 :                : 
                              10576                 :                : /*
                              10577                 :                :  * dumpDumpableObject
                              10578                 :                :  *
                              10579                 :                :  * This routine and its subsidiaries are responsible for creating
                              10580                 :                :  * ArchiveEntries (TOC objects) for each object to be dumped.
                              10581                 :                :  */
                              10582                 :                : static void
  860                         10583                 :         664248 : dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                              10584                 :                : {
                              10585                 :                :     /*
                              10586                 :                :      * Clear any dump-request bits for components that don't exist for this
                              10587                 :                :      * object.  (This makes it safe to initially use DUMP_COMPONENT_ALL as the
                              10588                 :                :      * request for every kind of object.)
                              10589                 :                :      */
                              10590                 :         664248 :     dobj->dump &= dobj->components;
                              10591                 :                : 
                              10592                 :                :     /* Now, short-circuit if there's nothing to be done here. */
                              10593         [ +  + ]:         664248 :     if (dobj->dump == 0)
                              10594                 :         605568 :         return;
                              10595                 :                : 
 7435                         10596   [ +  +  +  +  :          58680 :     switch (dobj->objType)
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                     +  +  +  +  +  
                                           +  +  - ]
                              10597                 :                :     {
                              10598                 :            397 :         case DO_NAMESPACE:
 1159 peter@eisentraut.org    10599                 :            397 :             dumpNamespace(fout, (const NamespaceInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10600                 :            397 :             break;
 4814                         10601                 :             19 :         case DO_EXTENSION:
 1159 peter@eisentraut.org    10602                 :             19 :             dumpExtension(fout, (const ExtensionInfo *) dobj);
 4814 tgl@sss.pgh.pa.us       10603                 :             19 :             break;
 7435                         10604                 :            650 :         case DO_TYPE:
 1159 peter@eisentraut.org    10605                 :            650 :             dumpType(fout, (const TypeInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10606                 :            650 :             break;
 6618                         10607                 :             74 :         case DO_SHELL_TYPE:
 1159 peter@eisentraut.org    10608                 :             74 :             dumpShellType(fout, (const ShellTypeInfo *) dobj);
 6618 tgl@sss.pgh.pa.us       10609                 :             74 :             break;
 7435                         10610                 :           1789 :         case DO_FUNC:
 1159 peter@eisentraut.org    10611                 :           1789 :             dumpFunc(fout, (const FuncInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10612                 :           1789 :             break;
                              10613                 :            293 :         case DO_AGG:
 1159 peter@eisentraut.org    10614                 :            293 :             dumpAgg(fout, (const AggInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10615                 :            293 :             break;
                              10616                 :            907 :         case DO_OPERATOR:
 1159 peter@eisentraut.org    10617                 :            907 :             dumpOpr(fout, (const OprInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10618                 :            907 :             break;
 2944 alvherre@alvh.no-ip.    10619                 :             82 :         case DO_ACCESS_METHOD:
 1159 peter@eisentraut.org    10620                 :             82 :             dumpAccessMethod(fout, (const AccessMethodInfo *) dobj);
 2944 alvherre@alvh.no-ip.    10621                 :             82 :             break;
 7435 tgl@sss.pgh.pa.us       10622                 :            309 :         case DO_OPCLASS:
 1159 peter@eisentraut.org    10623                 :            309 :             dumpOpclass(fout, (const OpclassInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10624                 :            309 :             break;
 6291                         10625                 :            259 :         case DO_OPFAMILY:
 1159 peter@eisentraut.org    10626                 :            259 :             dumpOpfamily(fout, (const OpfamilyInfo *) dobj);
 6291 tgl@sss.pgh.pa.us       10627                 :            259 :             break;
 4810 peter_e@gmx.net         10628                 :           1547 :         case DO_COLLATION:
 1159 peter@eisentraut.org    10629                 :           1547 :             dumpCollation(fout, (const CollInfo *) dobj);
 4810 peter_e@gmx.net         10630                 :           1547 :             break;
 7435 tgl@sss.pgh.pa.us       10631                 :            167 :         case DO_CONVERSION:
 1159 peter@eisentraut.org    10632                 :            167 :             dumpConversion(fout, (const ConvInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10633                 :            167 :             break;
                              10634                 :          25269 :         case DO_TABLE:
 1159 peter@eisentraut.org    10635                 :          25269 :             dumpTable(fout, (const TableInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10636                 :          25269 :             break;
 1189                         10637                 :           1259 :         case DO_TABLE_ATTACH:
 1159 peter@eisentraut.org    10638                 :           1259 :             dumpTableAttach(fout, (const TableAttachInfo *) dobj);
 1189 tgl@sss.pgh.pa.us       10639                 :           1259 :             break;
 7435                         10640                 :            818 :         case DO_ATTRDEF:
 1159 peter@eisentraut.org    10641                 :            818 :             dumpAttrDef(fout, (const AttrDefInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10642                 :            818 :             break;
                              10643                 :           2216 :         case DO_INDEX:
 1159 peter@eisentraut.org    10644                 :           2216 :             dumpIndex(fout, (const IndxInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10645                 :           2216 :             break;
 2277 alvherre@alvh.no-ip.    10646                 :            567 :         case DO_INDEX_ATTACH:
 1159 peter@eisentraut.org    10647                 :            567 :             dumpIndexAttach(fout, (const IndexAttachInfo *) dobj);
 2277 alvherre@alvh.no-ip.    10648                 :            567 :             break;
 2578                         10649                 :            136 :         case DO_STATSEXT:
 1159 peter@eisentraut.org    10650                 :            136 :             dumpStatisticsExt(fout, (const StatsExtInfo *) dobj);
 2578 alvherre@alvh.no-ip.    10651                 :            136 :             break;
 4060 kgrittn@postgresql.o    10652                 :            365 :         case DO_REFRESH_MATVIEW:
 1159 peter@eisentraut.org    10653                 :            365 :             refreshMatViewData(fout, (const TableDataInfo *) dobj);
 4060 kgrittn@postgresql.o    10654                 :            365 :             break;
 7435 tgl@sss.pgh.pa.us       10655                 :            940 :         case DO_RULE:
 1159 peter@eisentraut.org    10656                 :            940 :             dumpRule(fout, (const RuleInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10657                 :            940 :             break;
                              10658                 :            508 :         case DO_TRIGGER:
 1159 peter@eisentraut.org    10659                 :            508 :             dumpTrigger(fout, (const TriggerInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10660                 :            508 :             break;
 4288 rhaas@postgresql.org    10661                 :             43 :         case DO_EVENT_TRIGGER:
 1159 peter@eisentraut.org    10662                 :             43 :             dumpEventTrigger(fout, (const EventTriggerInfo *) dobj);
 4288 rhaas@postgresql.org    10663                 :             43 :             break;
 7435 tgl@sss.pgh.pa.us       10664                 :           1855 :         case DO_CONSTRAINT:
 1159 peter@eisentraut.org    10665                 :           1855 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10666                 :           1855 :             break;
                              10667                 :            178 :         case DO_FK_CONSTRAINT:
 1159 peter@eisentraut.org    10668                 :            178 :             dumpConstraint(fout, (const ConstraintInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10669                 :            178 :             break;
                              10670                 :             84 :         case DO_PROCLANG:
 1159 peter@eisentraut.org    10671                 :             84 :             dumpProcLang(fout, (const ProcLangInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10672                 :             84 :             break;
                              10673                 :             68 :         case DO_CAST:
 1159 peter@eisentraut.org    10674                 :             68 :             dumpCast(fout, (const CastInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10675                 :             68 :             break;
 3276 peter_e@gmx.net         10676                 :             43 :         case DO_TRANSFORM:
 1159 peter@eisentraut.org    10677                 :             43 :             dumpTransform(fout, (const TransformInfo *) dobj);
 3276 peter_e@gmx.net         10678                 :             43 :             break;
 2791                         10679                 :            385 :         case DO_SEQUENCE_SET:
 1159 peter@eisentraut.org    10680                 :            385 :             dumpSequenceData(fout, (const TableDataInfo *) dobj);
 2791 peter_e@gmx.net         10681                 :            385 :             break;
 7435 tgl@sss.pgh.pa.us       10682                 :           3616 :         case DO_TABLE_DATA:
 1159 peter@eisentraut.org    10683                 :           3616 :             dumpTableData(fout, (const TableDataInfo *) dobj);
 7435 tgl@sss.pgh.pa.us       10684                 :           3616 :             break;
 5565                         10685                 :          11878 :         case DO_DUMMY_TYPE:
                              10686                 :                :             /* table rowtypes and array types are never dumped separately */
 7347                         10687                 :          11878 :             break;
 6081                         10688                 :             40 :         case DO_TSPARSER:
 1159 peter@eisentraut.org    10689                 :             40 :             dumpTSParser(fout, (const TSParserInfo *) dobj);
 6081 tgl@sss.pgh.pa.us       10690                 :             40 :             break;
                              10691                 :            113 :         case DO_TSDICT:
 1159 peter@eisentraut.org    10692                 :            113 :             dumpTSDictionary(fout, (const TSDictInfo *) dobj);
 6081 tgl@sss.pgh.pa.us       10693                 :            113 :             break;
                              10694                 :             44 :         case DO_TSTEMPLATE:
 1159 peter@eisentraut.org    10695                 :             44 :             dumpTSTemplate(fout, (const TSTemplateInfo *) dobj);
 6081 tgl@sss.pgh.pa.us       10696                 :             44 :             break;
                              10697                 :             88 :         case DO_TSCONFIG:
 1159 peter@eisentraut.org    10698                 :             88 :             dumpTSConfig(fout, (const TSConfigInfo *) dobj);
 6081 tgl@sss.pgh.pa.us       10699                 :             88 :             break;
 5595 peter_e@gmx.net         10700                 :             53 :         case DO_FDW:
 1159 peter@eisentraut.org    10701                 :             53 :             dumpForeignDataWrapper(fout, (const FdwInfo *) dobj);
 5595 peter_e@gmx.net         10702                 :             53 :             break;
                              10703                 :             57 :         case DO_FOREIGN_SERVER:
 1159 peter@eisentraut.org    10704                 :             57 :             dumpForeignServer(fout, (const ForeignServerInfo *) dobj);
 5595 peter_e@gmx.net         10705                 :             57 :             break;
 5305 tgl@sss.pgh.pa.us       10706                 :            154 :         case DO_DEFAULT_ACL:
 1159 peter@eisentraut.org    10707                 :            154 :             dumpDefaultACL(fout, (const DefaultACLInfo *) dobj);
 5305 tgl@sss.pgh.pa.us       10708                 :            154 :             break;
  496 peter@eisentraut.org    10709                 :             79 :         case DO_LARGE_OBJECT:
                              10710                 :             79 :             dumpLO(fout, (const LoInfo *) dobj);
 5169 tgl@sss.pgh.pa.us       10711                 :             79 :             break;
  496 peter@eisentraut.org    10712                 :             79 :         case DO_LARGE_OBJECT_DATA:
 2930 sfrost@snowman.net      10713         [ +  - ]:             79 :             if (dobj->dump & DUMP_COMPONENT_DATA)
                              10714                 :                :             {
                              10715                 :                :                 LoInfo     *loinfo;
                              10716                 :                :                 TocEntry   *te;
                              10717                 :                : 
   13 tgl@sss.pgh.pa.us       10718                 :GNC          79 :                 loinfo = (LoInfo *) findObjectByDumpId(dobj->dependencies[0]);
                              10719         [ -  + ]:             79 :                 if (loinfo == NULL)
   13 tgl@sss.pgh.pa.us       10720                 :UNC           0 :                     pg_fatal("missing metadata for large objects \"%s\"",
                              10721                 :                :                              dobj->name);
                              10722                 :                : 
 2039 tgl@sss.pgh.pa.us       10723                 :CBC          79 :                 te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
 1899 alvherre@alvh.no-ip.    10724                 :             79 :                                   ARCHIVE_OPTS(.tag = dobj->name,
                              10725                 :                :                                                .owner = loinfo->rolname,
                              10726                 :                :                                                .description = "BLOBS",
                              10727                 :                :                                                .section = SECTION_DATA,
                              10728                 :                :                                                .deps = dobj->dependencies,
                              10729                 :                :                                                .nDeps = dobj->nDeps,
                              10730                 :                :                                                .dumpFn = dumpLOs,
                              10731                 :                :                                                .dumpArg = loinfo));
                              10732                 :                : 
                              10733                 :                :                 /*
                              10734                 :                :                  * Set the TocEntry's dataLength in case we are doing a
                              10735                 :                :                  * parallel dump and want to order dump jobs by table size.
                              10736                 :                :                  * (We need some size estimate for every TocEntry with a
                              10737                 :                :                  * DataDumper function.)  We don't currently have any cheap
                              10738                 :                :                  * way to estimate the size of LOs, but fortunately it doesn't
                              10739                 :                :                  * matter too much as long as we get large batches of LOs
                              10740                 :                :                  * processed reasonably early.  Assume 8K per blob.
                              10741                 :                :                  */
   13 tgl@sss.pgh.pa.us       10742                 :GNC          79 :                 te->dataLength = loinfo->numlos * (pgoff_t) 8192;
                              10743                 :                :             }
 7347 tgl@sss.pgh.pa.us       10744                 :CBC          79 :             break;
 3426 sfrost@snowman.net      10745                 :            340 :         case DO_POLICY:
 1159 peter@eisentraut.org    10746                 :            340 :             dumpPolicy(fout, (const PolicyInfo *) dobj);
 3495 sfrost@snowman.net      10747                 :            340 :             break;
 2642 peter_e@gmx.net         10748                 :            153 :         case DO_PUBLICATION:
 1159 peter@eisentraut.org    10749                 :            153 :             dumpPublication(fout, (const PublicationInfo *) dobj);
 2642 peter_e@gmx.net         10750                 :            153 :             break;
                              10751                 :            256 :         case DO_PUBLICATION_REL:
 1159 peter@eisentraut.org    10752                 :            256 :             dumpPublicationTable(fout, (const PublicationRelInfo *) dobj);
 2642 peter_e@gmx.net         10753                 :            256 :             break;
  887 akapila@postgresql.o    10754                 :             75 :         case DO_PUBLICATION_TABLE_IN_SCHEMA:
  900                         10755                 :             75 :             dumpPublicationNamespace(fout,
                              10756                 :                :                                      (const PublicationSchemaInfo *) dobj);
                              10757                 :             75 :             break;
 2642 peter_e@gmx.net         10758                 :            116 :         case DO_SUBSCRIPTION:
 1159 peter@eisentraut.org    10759                 :            116 :             dumpSubscription(fout, (const SubscriptionInfo *) dobj);
 2642 peter_e@gmx.net         10760                 :            116 :             break;
  103 akapila@postgresql.o    10761                 :GNC           2 :         case DO_SUBSCRIPTION_REL:
                              10762                 :              2 :             dumpSubscriptionTable(fout, (const SubRelInfo *) dobj);
                              10763                 :              2 :             break;
 4311 tgl@sss.pgh.pa.us       10764                 :CBC         310 :         case DO_PRE_DATA_BOUNDARY:
                              10765                 :                :         case DO_POST_DATA_BOUNDARY:
                              10766                 :                :             /* never dumped, nothing to do */
                              10767                 :            310 :             break;
                              10768                 :                :     }
                              10769                 :                : }
                              10770                 :                : 
                              10771                 :                : /*
                              10772                 :                :  * dumpNamespace
                              10773                 :                :  *    writes out to fout the queries to recreate a user-defined namespace
                              10774                 :                :  */
                              10775                 :                : static void
 1159 peter@eisentraut.org    10776                 :            397 : dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo)
                              10777                 :                : {
 3014 tgl@sss.pgh.pa.us       10778                 :            397 :     DumpOptions *dopt = fout->dopt;
                              10779                 :                :     PQExpBuffer q;
                              10780                 :                :     PQExpBuffer delq;
                              10781                 :                :     char       *qnspname;
                              10782                 :                : 
                              10783                 :                :     /* Do nothing in data-only dump */
  860                         10784         [ +  + ]:            397 :     if (dopt->dataOnly)
 7435                         10785                 :             16 :         return;
                              10786                 :                : 
                              10787                 :            381 :     q = createPQExpBuffer();
                              10788                 :            381 :     delq = createPQExpBuffer();
                              10789                 :                : 
 4524 bruce@momjian.us        10790                 :            381 :     qnspname = pg_strdup(fmtId(nspinfo->dobj.name));
                              10791                 :                : 
 1021 noah@leadboat.com       10792         [ +  + ]:            381 :     if (nspinfo->create)
                              10793                 :                :     {
                              10794                 :            256 :         appendPQExpBuffer(delq, "DROP SCHEMA %s;\n", qnspname);
                              10795                 :            256 :         appendPQExpBuffer(q, "CREATE SCHEMA %s;\n", qnspname);
                              10796                 :                :     }
                              10797                 :                :     else
                              10798                 :                :     {
                              10799                 :                :         /* see selectDumpableNamespace() */
                              10800                 :            125 :         appendPQExpBufferStr(delq,
                              10801                 :                :                              "-- *not* dropping schema, since initdb creates it\n");
                              10802                 :            125 :         appendPQExpBufferStr(q,
                              10803                 :                :                              "-- *not* creating schema, since initdb creates it\n");
                              10804                 :                :     }
                              10805                 :                : 
 3470 alvherre@alvh.no-ip.    10806         [ +  + ]:            381 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       10807                 :             40 :         binary_upgrade_extension_member(q, &nspinfo->dobj,
                              10808                 :                :                                         "SCHEMA", qnspname, NULL);
                              10809                 :                : 
 2930 sfrost@snowman.net      10810         [ +  + ]:            381 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              10811                 :            165 :         ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    10812                 :            165 :                      ARCHIVE_OPTS(.tag = nspinfo->dobj.name,
                              10813                 :                :                                   .owner = nspinfo->rolname,
                              10814                 :                :                                   .description = "SCHEMA",
                              10815                 :                :                                   .section = SECTION_PRE_DATA,
                              10816                 :                :                                   .createStmt = q->data,
                              10817                 :                :                                   .dropStmt = delq->data));
                              10818                 :                : 
                              10819                 :                :     /* Dump Schema Comments and Security Labels */
 2930 sfrost@snowman.net      10820         [ +  + ]:            381 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              10821                 :                :     {
 1021 noah@leadboat.com       10822                 :            128 :         const char *initdb_comment = NULL;
                              10823                 :                : 
                              10824   [ +  +  +  + ]:            128 :         if (!nspinfo->create && strcmp(qnspname, "public") == 0)
  852 tgl@sss.pgh.pa.us       10825                 :            113 :             initdb_comment = "standard public schema";
 1021 noah@leadboat.com       10826                 :            128 :         dumpCommentExtended(fout, "SCHEMA", qnspname,
                              10827                 :            128 :                             NULL, nspinfo->rolname,
                              10828                 :            128 :                             nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId,
                              10829                 :                :                             initdb_comment);
                              10830                 :                :     }
                              10831                 :                : 
 2930 sfrost@snowman.net      10832         [ -  + ]:            381 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       10833                 :UBC           0 :         dumpSecLabel(fout, "SCHEMA", qnspname,
 2930 sfrost@snowman.net      10834                 :              0 :                      NULL, nspinfo->rolname,
                              10835                 :              0 :                      nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
                              10836                 :                : 
 2930 sfrost@snowman.net      10837         [ +  + ]:CBC         381 :     if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       10838                 :            295 :         dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
                              10839                 :                :                 qnspname, NULL, NULL,
   13 tgl@sss.pgh.pa.us       10840                 :GNC         295 :                 NULL, nspinfo->rolname, &nspinfo->dacl);
                              10841                 :                : 
 7435 tgl@sss.pgh.pa.us       10842                 :CBC         381 :     free(qnspname);
                              10843                 :                : 
 8010                         10844                 :            381 :     destroyPQExpBuffer(q);
                              10845                 :            381 :     destroyPQExpBuffer(delq);
                              10846                 :                : }
                              10847                 :                : 
                              10848                 :                : /*
                              10849                 :                :  * dumpExtension
                              10850                 :                :  *    writes out to fout the queries to recreate an extension
                              10851                 :                :  */
                              10852                 :                : static void
 1159 peter@eisentraut.org    10853                 :             19 : dumpExtension(Archive *fout, const ExtensionInfo *extinfo)
                              10854                 :                : {
 3014 tgl@sss.pgh.pa.us       10855                 :             19 :     DumpOptions *dopt = fout->dopt;
                              10856                 :                :     PQExpBuffer q;
                              10857                 :                :     PQExpBuffer delq;
                              10858                 :                :     char       *qextname;
                              10859                 :                : 
                              10860                 :                :     /* Do nothing in data-only dump */
  860                         10861         [ +  + ]:             19 :     if (dopt->dataOnly)
 4814                         10862                 :              1 :         return;
                              10863                 :                : 
                              10864                 :             18 :     q = createPQExpBuffer();
                              10865                 :             18 :     delq = createPQExpBuffer();
                              10866                 :                : 
 4524 bruce@momjian.us        10867                 :             18 :     qextname = pg_strdup(fmtId(extinfo->dobj.name));
                              10868                 :                : 
 4814 tgl@sss.pgh.pa.us       10869                 :             18 :     appendPQExpBuffer(delq, "DROP EXTENSION %s;\n", qextname);
                              10870                 :                : 
 3470 alvherre@alvh.no-ip.    10871         [ +  + ]:             18 :     if (!dopt->binary_upgrade)
                              10872                 :                :     {
                              10873                 :                :         /*
                              10874                 :                :          * In a regular dump, we simply create the extension, intentionally
                              10875                 :                :          * not specifying a version, so that the destination installation's
                              10876                 :                :          * default version is used.
                              10877                 :                :          *
                              10878                 :                :          * Use of IF NOT EXISTS here is unlike our behavior for other object
                              10879                 :                :          * types; but there are various scenarios in which it's convenient to
                              10880                 :                :          * manually create the desired extension before restoring, so we
                              10881                 :                :          * prefer to allow it to exist already.
                              10882                 :                :          */
 4790 tgl@sss.pgh.pa.us       10883                 :             17 :         appendPQExpBuffer(q, "CREATE EXTENSION IF NOT EXISTS %s WITH SCHEMA %s;\n",
 4813                         10884                 :             17 :                           qextname, fmtId(extinfo->namespace));
                              10885                 :                :     }
                              10886                 :                :     else
                              10887                 :                :     {
                              10888                 :                :         /*
                              10889                 :                :          * In binary-upgrade mode, it's critical to reproduce the state of the
                              10890                 :                :          * database exactly, so our procedure is to create an empty extension,
                              10891                 :                :          * restore all the contained objects normally, and add them to the
                              10892                 :                :          * extension one by one.  This function performs just the first of
                              10893                 :                :          * those steps.  binary_upgrade_extension_member() takes care of
                              10894                 :                :          * adding member objects as they're created.
                              10895                 :                :          */
                              10896                 :                :         int         i;
                              10897                 :                :         int         n;
                              10898                 :                : 
 3800 heikki.linnakangas@i    10899                 :              1 :         appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
                              10900                 :                : 
                              10901                 :                :         /*
                              10902                 :                :          * We unconditionally create the extension, so we must drop it if it
                              10903                 :                :          * exists.  This could happen if the user deleted 'plpgsql' and then
                              10904                 :                :          * readded it, causing its oid to be greater than g_last_builtin_oid.
                              10905                 :                :          */
 4302 bruce@momjian.us        10906                 :              1 :         appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
                              10907                 :                : 
 3800 heikki.linnakangas@i    10908                 :              1 :         appendPQExpBufferStr(q,
                              10909                 :                :                              "SELECT pg_catalog.binary_upgrade_create_empty_extension(");
 4813 tgl@sss.pgh.pa.us       10910                 :              1 :         appendStringLiteralAH(q, extinfo->dobj.name, fout);
 3800 heikki.linnakangas@i    10911                 :              1 :         appendPQExpBufferStr(q, ", ");
 4813 tgl@sss.pgh.pa.us       10912                 :              1 :         appendStringLiteralAH(q, extinfo->namespace, fout);
 3800 heikki.linnakangas@i    10913                 :              1 :         appendPQExpBufferStr(q, ", ");
 4813 tgl@sss.pgh.pa.us       10914         [ +  - ]:              1 :         appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
 4811                         10915                 :              1 :         appendStringLiteralAH(q, extinfo->extversion, fout);
 3800 heikki.linnakangas@i    10916                 :              1 :         appendPQExpBufferStr(q, ", ");
                              10917                 :                : 
                              10918                 :                :         /*
                              10919                 :                :          * Note that we're pushing extconfig (an OID array) back into
                              10920                 :                :          * pg_extension exactly as-is.  This is OK because pg_class OIDs are
                              10921                 :                :          * preserved in binary upgrade.
                              10922                 :                :          */
 4813 tgl@sss.pgh.pa.us       10923         [ +  - ]:              1 :         if (strlen(extinfo->extconfig) > 2)
                              10924                 :              1 :             appendStringLiteralAH(q, extinfo->extconfig, fout);
                              10925                 :                :         else
 3800 heikki.linnakangas@i    10926                 :UBC           0 :             appendPQExpBufferStr(q, "NULL");
 3800 heikki.linnakangas@i    10927                 :CBC           1 :         appendPQExpBufferStr(q, ", ");
 4813 tgl@sss.pgh.pa.us       10928         [ +  - ]:              1 :         if (strlen(extinfo->extcondition) > 2)
                              10929                 :              1 :             appendStringLiteralAH(q, extinfo->extcondition, fout);
                              10930                 :                :         else
 3800 heikki.linnakangas@i    10931                 :UBC           0 :             appendPQExpBufferStr(q, "NULL");
 3800 heikki.linnakangas@i    10932                 :CBC           1 :         appendPQExpBufferStr(q, ", ");
                              10933                 :              1 :         appendPQExpBufferStr(q, "ARRAY[");
 4813 tgl@sss.pgh.pa.us       10934                 :              1 :         n = 0;
                              10935         [ +  + ]:              2 :         for (i = 0; i < extinfo->dobj.nDeps; i++)
                              10936                 :                :         {
                              10937                 :                :             DumpableObject *extobj;
                              10938                 :                : 
                              10939                 :              1 :             extobj = findObjectByDumpId(extinfo->dobj.dependencies[i]);
                              10940   [ +  -  -  + ]:              1 :             if (extobj && extobj->objType == DO_EXTENSION)
                              10941                 :                :             {
 4813 tgl@sss.pgh.pa.us       10942         [ #  # ]:UBC           0 :                 if (n++ > 0)
 3800 heikki.linnakangas@i    10943                 :              0 :                     appendPQExpBufferChar(q, ',');
 4813 tgl@sss.pgh.pa.us       10944                 :              0 :                 appendStringLiteralAH(q, extobj->name, fout);
                              10945                 :                :             }
                              10946                 :                :         }
 3800 heikki.linnakangas@i    10947                 :CBC           1 :         appendPQExpBufferStr(q, "]::pg_catalog.text[]");
                              10948                 :              1 :         appendPQExpBufferStr(q, ");\n");
                              10949                 :                :     }
                              10950                 :                : 
 2930 sfrost@snowman.net      10951         [ +  - ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              10952                 :             18 :         ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    10953                 :             18 :                      ARCHIVE_OPTS(.tag = extinfo->dobj.name,
                              10954                 :                :                                   .description = "EXTENSION",
                              10955                 :                :                                   .section = SECTION_PRE_DATA,
                              10956                 :                :                                   .createStmt = q->data,
                              10957                 :                :                                   .dropStmt = delq->data));
                              10958                 :                : 
                              10959                 :                :     /* Dump Extension Comments and Security Labels */
 2930 sfrost@snowman.net      10960         [ +  - ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       10961                 :             18 :         dumpComment(fout, "EXTENSION", qextname,
                              10962                 :                :                     NULL, "",
 2930 sfrost@snowman.net      10963                 :             18 :                     extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
                              10964                 :                : 
                              10965         [ -  + ]:             18 :     if (extinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       10966                 :UBC           0 :         dumpSecLabel(fout, "EXTENSION", qextname,
                              10967                 :                :                      NULL, "",
 2930 sfrost@snowman.net      10968                 :              0 :                      extinfo->dobj.catId, 0, extinfo->dobj.dumpId);
                              10969                 :                : 
 4814 tgl@sss.pgh.pa.us       10970                 :CBC          18 :     free(qextname);
                              10971                 :                : 
                              10972                 :             18 :     destroyPQExpBuffer(q);
                              10973                 :             18 :     destroyPQExpBuffer(delq);
                              10974                 :                : }
                              10975                 :                : 
                              10976                 :                : /*
                              10977                 :                :  * dumpType
                              10978                 :                :  *    writes out to fout the queries to recreate a user-defined type
                              10979                 :                :  */
                              10980                 :                : static void
 1159 peter@eisentraut.org    10981                 :            650 : dumpType(Archive *fout, const TypeInfo *tyinfo)
                              10982                 :                : {
 3014 tgl@sss.pgh.pa.us       10983                 :            650 :     DumpOptions *dopt = fout->dopt;
                              10984                 :                : 
                              10985                 :                :     /* Do nothing in data-only dump */
  860                         10986         [ +  + ]:            650 :     if (dopt->dataOnly)
 7435                         10987                 :             22 :         return;
                              10988                 :                : 
                              10989                 :                :     /* Dump out in proper style */
 5226 bruce@momjian.us        10990         [ +  + ]:            628 :     if (tyinfo->typtype == TYPTYPE_BASE)
 3014 tgl@sss.pgh.pa.us       10991                 :            141 :         dumpBaseType(fout, tyinfo);
 5226 bruce@momjian.us        10992         [ +  + ]:            487 :     else if (tyinfo->typtype == TYPTYPE_DOMAIN)
 3014 tgl@sss.pgh.pa.us       10993                 :            131 :         dumpDomain(fout, tyinfo);
 5226 bruce@momjian.us        10994         [ +  + ]:            356 :     else if (tyinfo->typtype == TYPTYPE_COMPOSITE)
 3014 tgl@sss.pgh.pa.us       10995                 :            134 :         dumpCompositeType(fout, tyinfo);
 5226 bruce@momjian.us        10996         [ +  + ]:            222 :     else if (tyinfo->typtype == TYPTYPE_ENUM)
 3014 tgl@sss.pgh.pa.us       10997                 :             58 :         dumpEnumType(fout, tyinfo);
 4546 heikki.linnakangas@i    10998         [ +  + ]:            164 :     else if (tyinfo->typtype == TYPTYPE_RANGE)
 3014 tgl@sss.pgh.pa.us       10999                 :             98 :         dumpRangeType(fout, tyinfo);
 3176                         11000   [ +  -  +  + ]:             66 :     else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined)
 3014                         11001                 :             41 :         dumpUndefinedType(fout, tyinfo);
                              11002                 :                :     else
 1840 peter@eisentraut.org    11003                 :             25 :         pg_log_warning("typtype of data type \"%s\" appears to be invalid",
                              11004                 :                :                        tyinfo->dobj.name);
                              11005                 :                : }
                              11006                 :                : 
                              11007                 :                : /*
                              11008                 :                :  * dumpEnumType
                              11009                 :                :  *    writes out to fout the queries to recreate a user-defined enum type
                              11010                 :                :  */
                              11011                 :                : static void
 1159                         11012                 :             58 : dumpEnumType(Archive *fout, const TypeInfo *tyinfo)
                              11013                 :                : {
 3014 tgl@sss.pgh.pa.us       11014                 :             58 :     DumpOptions *dopt = fout->dopt;
 6222                         11015                 :             58 :     PQExpBuffer q = createPQExpBuffer();
                              11016                 :             58 :     PQExpBuffer delq = createPQExpBuffer();
                              11017                 :             58 :     PQExpBuffer query = createPQExpBuffer();
                              11018                 :                :     PGresult   *res;
                              11019                 :                :     int         num,
                              11020                 :                :                 i;
                              11021                 :                :     Oid         enum_oid;
                              11022                 :                :     char       *qtypname;
                              11023                 :                :     char       *qualtypname;
                              11024                 :                :     char       *label;
                              11025                 :                :     int         i_enumlabel;
                              11026                 :                :     int         i_oid;
                              11027                 :                : 
  860                         11028         [ +  + ]:             58 :     if (!fout->is_prepared[PREPQUERY_DUMPENUMTYPE])
                              11029                 :                :     {
                              11030                 :                :         /* Set up query for enum-specific details */
                              11031                 :             43 :         appendPQExpBufferStr(query,
                              11032                 :                :                              "PREPARE dumpEnumType(pg_catalog.oid) AS\n"
                              11033                 :                :                              "SELECT oid, enumlabel "
                              11034                 :                :                              "FROM pg_catalog.pg_enum "
                              11035                 :                :                              "WHERE enumtypid = $1 "
                              11036                 :                :                              "ORDER BY enumsortorder");
                              11037                 :                : 
                              11038                 :             43 :         ExecuteSqlStatement(fout, query->data);
                              11039                 :                : 
                              11040                 :             43 :         fout->is_prepared[PREPQUERY_DUMPENUMTYPE] = true;
                              11041                 :                :     }
                              11042                 :                : 
                              11043                 :             58 :     printfPQExpBuffer(query,
                              11044                 :                :                       "EXECUTE dumpEnumType('%u')",
                              11045                 :             58 :                       tyinfo->dobj.catId.oid);
                              11046                 :                : 
 4450 rhaas@postgresql.org    11047                 :             58 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11048                 :                : 
 6222 tgl@sss.pgh.pa.us       11049                 :             58 :     num = PQntuples(res);
                              11050                 :                : 
 4144                         11051                 :             58 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11052                 :             58 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11053                 :                : 
                              11054                 :                :     /*
                              11055                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              11056                 :                :      * functions are generic and do not get dropped.
                              11057                 :                :      */
                              11058                 :             58 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              11059                 :                : 
 3470 alvherre@alvh.no-ip.    11060         [ +  + ]:             58 :     if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    11061                 :              5 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2388 tgl@sss.pgh.pa.us       11062                 :              5 :                                                  tyinfo->dobj.catId.oid,
                              11063                 :                :                                                  false, false);
                              11064                 :                : 
 5222 bruce@momjian.us        11065                 :             58 :     appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
                              11066                 :                :                       qualtypname);
                              11067                 :                : 
 3470 alvherre@alvh.no-ip.    11068         [ +  + ]:             58 :     if (!dopt->binary_upgrade)
                              11069                 :                :     {
  961 dgustafsson@postgres    11070                 :             53 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              11071                 :                : 
                              11072                 :                :         /* Labels with server-assigned oids */
 5222 bruce@momjian.us        11073         [ +  + ]:            378 :         for (i = 0; i < num; i++)
                              11074                 :                :         {
  961 dgustafsson@postgres    11075                 :            325 :             label = PQgetvalue(res, i, i_enumlabel);
 5222 bruce@momjian.us        11076         [ +  + ]:            325 :             if (i > 0)
 3800 heikki.linnakangas@i    11077                 :            272 :                 appendPQExpBufferChar(q, ',');
                              11078                 :            325 :             appendPQExpBufferStr(q, "\n    ");
 5222 bruce@momjian.us        11079                 :            325 :             appendStringLiteralAH(q, label, fout);
                              11080                 :                :         }
                              11081                 :                :     }
                              11082                 :                : 
 3800 heikki.linnakangas@i    11083                 :             58 :     appendPQExpBufferStr(q, "\n);\n");
                              11084                 :                : 
 3470 alvherre@alvh.no-ip.    11085         [ +  + ]:             58 :     if (dopt->binary_upgrade)
                              11086                 :                :     {
  961 dgustafsson@postgres    11087                 :              5 :         i_oid = PQfnumber(res, "oid");
                              11088                 :              5 :         i_enumlabel = PQfnumber(res, "enumlabel");
                              11089                 :                : 
                              11090                 :                :         /* Labels with dump-assigned (preserved) oids */
 5222 bruce@momjian.us        11091         [ +  + ]:             58 :         for (i = 0; i < num; i++)
                              11092                 :                :         {
  961 dgustafsson@postgres    11093                 :             53 :             enum_oid = atooid(PQgetvalue(res, i, i_oid));
                              11094                 :             53 :             label = PQgetvalue(res, i, i_enumlabel);
                              11095                 :                : 
 5222 bruce@momjian.us        11096         [ +  + ]:             53 :             if (i == 0)
 3800 heikki.linnakangas@i    11097                 :              5 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
 5222 bruce@momjian.us        11098                 :             53 :             appendPQExpBuffer(q,
                              11099                 :                :                               "SELECT pg_catalog.binary_upgrade_set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                              11100                 :                :                               enum_oid);
 2239 tgl@sss.pgh.pa.us       11101                 :             53 :             appendPQExpBuffer(q, "ALTER TYPE %s ADD VALUE ", qualtypname);
 5222 bruce@momjian.us        11102                 :             53 :             appendStringLiteralAH(q, label, fout);
 3800 heikki.linnakangas@i    11103                 :             53 :             appendPQExpBufferStr(q, ";\n\n");
                              11104                 :                :         }
                              11105                 :                :     }
                              11106                 :                : 
 3470 alvherre@alvh.no-ip.    11107         [ +  + ]:             58 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       11108                 :              5 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11109                 :                :                                         "TYPE", qtypname,
                              11110                 :              5 :                                         tyinfo->dobj.namespace->dobj.name);
                              11111                 :                : 
 2930 sfrost@snowman.net      11112         [ +  - ]:             58 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11113                 :             58 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11114                 :             58 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11115                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11116                 :                :                                   .owner = tyinfo->rolname,
                              11117                 :                :                                   .description = "TYPE",
                              11118                 :                :                                   .section = SECTION_PRE_DATA,
                              11119                 :                :                                   .createStmt = q->data,
                              11120                 :                :                                   .dropStmt = delq->data));
                              11121                 :                : 
                              11122                 :                :     /* Dump Type Comments and Security Labels */
 2930 sfrost@snowman.net      11123         [ +  + ]:             58 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11124                 :             36 :         dumpComment(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11125                 :             36 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11126                 :             36 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11127                 :                : 
                              11128         [ -  + ]:             58 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11129                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11130                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11131                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11132                 :                : 
 2930 sfrost@snowman.net      11133         [ +  + ]:CBC          58 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11134                 :             36 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11135                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11136                 :             36 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11137                 :GNC          36 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11138                 :                : 
 4546 heikki.linnakangas@i    11139                 :CBC          58 :     PQclear(res);
                              11140                 :             58 :     destroyPQExpBuffer(q);
                              11141                 :             58 :     destroyPQExpBuffer(delq);
                              11142                 :             58 :     destroyPQExpBuffer(query);
 2239 tgl@sss.pgh.pa.us       11143                 :             58 :     free(qtypname);
                              11144                 :             58 :     free(qualtypname);
 4546 heikki.linnakangas@i    11145                 :             58 : }
                              11146                 :                : 
                              11147                 :                : /*
                              11148                 :                :  * dumpRangeType
                              11149                 :                :  *    writes out to fout the queries to recreate a user-defined range type
                              11150                 :                :  */
                              11151                 :                : static void
 1159 peter@eisentraut.org    11152                 :             98 : dumpRangeType(Archive *fout, const TypeInfo *tyinfo)
                              11153                 :                : {
 3014 tgl@sss.pgh.pa.us       11154                 :             98 :     DumpOptions *dopt = fout->dopt;
 4546 heikki.linnakangas@i    11155                 :             98 :     PQExpBuffer q = createPQExpBuffer();
                              11156                 :             98 :     PQExpBuffer delq = createPQExpBuffer();
                              11157                 :             98 :     PQExpBuffer query = createPQExpBuffer();
                              11158                 :                :     PGresult   *res;
                              11159                 :                :     Oid         collationOid;
                              11160                 :                :     char       *qtypname;
                              11161                 :                :     char       *qualtypname;
                              11162                 :                :     char       *procname;
                              11163                 :                : 
  860 tgl@sss.pgh.pa.us       11164         [ +  + ]:             98 :     if (!fout->is_prepared[PREPQUERY_DUMPRANGETYPE])
                              11165                 :                :     {
                              11166                 :                :         /* Set up query for range-specific details */
                              11167                 :             42 :         appendPQExpBufferStr(query,
                              11168                 :                :                              "PREPARE dumpRangeType(pg_catalog.oid) AS\n");
                              11169                 :                : 
                              11170                 :             42 :         appendPQExpBufferStr(query,
                              11171                 :                :                              "SELECT ");
                              11172                 :                : 
                              11173         [ +  - ]:             42 :         if (fout->remoteVersion >= 140000)
                              11174                 :             42 :             appendPQExpBufferStr(query,
                              11175                 :                :                                  "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, ");
                              11176                 :                :         else
  860 tgl@sss.pgh.pa.us       11177                 :UBC           0 :             appendPQExpBufferStr(query,
                              11178                 :                :                                  "NULL AS rngmultitype, ");
                              11179                 :                : 
  860 tgl@sss.pgh.pa.us       11180                 :CBC          42 :         appendPQExpBufferStr(query,
                              11181                 :                :                              "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                              11182                 :                :                              "opc.opcname AS opcname, "
                              11183                 :                :                              "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
                              11184                 :                :                              "  WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
                              11185                 :                :                              "opc.opcdefault, "
                              11186                 :                :                              "CASE WHEN rngcollation = st.typcollation THEN 0 "
                              11187                 :                :                              "     ELSE rngcollation END AS collation, "
                              11188                 :                :                              "rngcanonical, rngsubdiff "
                              11189                 :                :                              "FROM pg_catalog.pg_range r, pg_catalog.pg_type st, "
                              11190                 :                :                              "     pg_catalog.pg_opclass opc "
                              11191                 :                :                              "WHERE st.oid = rngsubtype AND opc.oid = rngsubopc AND "
                              11192                 :                :                              "rngtypid = $1");
                              11193                 :                : 
                              11194                 :             42 :         ExecuteSqlStatement(fout, query->data);
                              11195                 :                : 
                              11196                 :             42 :         fout->is_prepared[PREPQUERY_DUMPRANGETYPE] = true;
                              11197                 :                :     }
                              11198                 :                : 
                              11199                 :             98 :     printfPQExpBuffer(query,
                              11200                 :                :                       "EXECUTE dumpRangeType('%u')",
 4546 heikki.linnakangas@i    11201                 :             98 :                       tyinfo->dobj.catId.oid);
                              11202                 :                : 
 4441 rhaas@postgresql.org    11203                 :             98 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              11204                 :                : 
 4144 tgl@sss.pgh.pa.us       11205                 :             98 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11206                 :             98 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11207                 :                : 
                              11208                 :                :     /*
                              11209                 :                :      * CASCADE shouldn't be required here as for normal types since the I/O
                              11210                 :                :      * functions are generic and do not get dropped.
                              11211                 :                :      */
                              11212                 :             98 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              11213                 :                : 
 3470 alvherre@alvh.no-ip.    11214         [ +  + ]:             98 :     if (dopt->binary_upgrade)
 2388 tgl@sss.pgh.pa.us       11215                 :              6 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              11216                 :              6 :                                                  tyinfo->dobj.catId.oid,
                              11217                 :                :                                                  false, true);
                              11218                 :                : 
 4546 heikki.linnakangas@i    11219                 :             98 :     appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
                              11220                 :                :                       qualtypname);
                              11221                 :                : 
 4529 tgl@sss.pgh.pa.us       11222                 :             98 :     appendPQExpBuffer(q, "\n    subtype = %s",
                              11223                 :                :                       PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
                              11224                 :                : 
 1211 akorotkov@postgresql    11225         [ +  - ]:             98 :     if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype")))
                              11226                 :             98 :         appendPQExpBuffer(q, ",\n    multirange_type_name = %s",
                              11227                 :                :                           PQgetvalue(res, 0, PQfnumber(res, "rngmultitype")));
                              11228                 :                : 
                              11229                 :                :     /* print subtype_opclass only if not default for subtype */
 4529 tgl@sss.pgh.pa.us       11230         [ +  + ]:             98 :     if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
                              11231                 :                :     {
 4326 bruce@momjian.us        11232                 :             36 :         char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
                              11233                 :             36 :         char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
                              11234                 :                : 
 4529 tgl@sss.pgh.pa.us       11235                 :             36 :         appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                              11236                 :                :                           fmtId(nspname));
 3800 heikki.linnakangas@i    11237                 :             36 :         appendPQExpBufferStr(q, fmtId(opcname));
                              11238                 :                :     }
                              11239                 :                : 
 4529 tgl@sss.pgh.pa.us       11240                 :             98 :     collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
 4546 heikki.linnakangas@i    11241         [ +  + ]:             98 :     if (OidIsValid(collationOid))
                              11242                 :                :     {
 4529 tgl@sss.pgh.pa.us       11243                 :             41 :         CollInfo   *coll = findCollationByOid(collationOid);
                              11244                 :                : 
 4546 heikki.linnakangas@i    11245         [ +  - ]:             41 :         if (coll)
 2239 tgl@sss.pgh.pa.us       11246                 :             41 :             appendPQExpBuffer(q, ",\n    collation = %s",
                              11247                 :             41 :                               fmtQualifiedDumpable(coll));
                              11248                 :                :     }
                              11249                 :                : 
 4529                         11250                 :             98 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngcanonical"));
                              11251         [ +  + ]:             98 :     if (strcmp(procname, "-") != 0)
                              11252                 :              3 :         appendPQExpBuffer(q, ",\n    canonical = %s", procname);
                              11253                 :                : 
                              11254                 :             98 :     procname = PQgetvalue(res, 0, PQfnumber(res, "rngsubdiff"));
                              11255         [ +  + ]:             98 :     if (strcmp(procname, "-") != 0)
                              11256                 :             11 :         appendPQExpBuffer(q, ",\n    subtype_diff = %s", procname);
                              11257                 :                : 
 3800 heikki.linnakangas@i    11258                 :             98 :     appendPQExpBufferStr(q, "\n);\n");
                              11259                 :                : 
 3470 alvherre@alvh.no-ip.    11260         [ +  + ]:             98 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       11261                 :              6 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11262                 :                :                                         "TYPE", qtypname,
                              11263                 :              6 :                                         tyinfo->dobj.namespace->dobj.name);
                              11264                 :                : 
 2930 sfrost@snowman.net      11265         [ +  - ]:             98 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11266                 :             98 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11267                 :             98 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11268                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11269                 :                :                                   .owner = tyinfo->rolname,
                              11270                 :                :                                   .description = "TYPE",
                              11271                 :                :                                   .section = SECTION_PRE_DATA,
                              11272                 :                :                                   .createStmt = q->data,
                              11273                 :                :                                   .dropStmt = delq->data));
                              11274                 :                : 
                              11275                 :                :     /* Dump Type Comments and Security Labels */
 2930 sfrost@snowman.net      11276         [ +  + ]:             98 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11277                 :             42 :         dumpComment(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11278                 :             42 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11279                 :             42 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11280                 :                : 
                              11281         [ -  + ]:             98 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11282                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11283                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11284                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11285                 :                : 
 2930 sfrost@snowman.net      11286         [ +  + ]:CBC          98 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11287                 :             36 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11288                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11289                 :             36 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11290                 :GNC          36 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11291                 :                : 
 6222 tgl@sss.pgh.pa.us       11292                 :CBC          98 :     PQclear(res);
                              11293                 :             98 :     destroyPQExpBuffer(q);
                              11294                 :             98 :     destroyPQExpBuffer(delq);
                              11295                 :             98 :     destroyPQExpBuffer(query);
 2239                         11296                 :             98 :     free(qtypname);
                              11297                 :             98 :     free(qualtypname);
 7435                         11298                 :             98 : }
                              11299                 :                : 
                              11300                 :                : /*
                              11301                 :                :  * dumpUndefinedType
                              11302                 :                :  *    writes out to fout the queries to recreate a !typisdefined type
                              11303                 :                :  *
                              11304                 :                :  * This is a shell type, but we use different terminology to distinguish
                              11305                 :                :  * this case from where we have to emit a shell type definition to break
                              11306                 :                :  * circular dependencies.  An undefined type shouldn't ever have anything
                              11307                 :                :  * depending on it.
                              11308                 :                :  */
                              11309                 :                : static void
 1159 peter@eisentraut.org    11310                 :             41 : dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo)
                              11311                 :                : {
 3014 tgl@sss.pgh.pa.us       11312                 :             41 :     DumpOptions *dopt = fout->dopt;
 3176                         11313                 :             41 :     PQExpBuffer q = createPQExpBuffer();
                              11314                 :             41 :     PQExpBuffer delq = createPQExpBuffer();
                              11315                 :                :     char       *qtypname;
                              11316                 :                :     char       *qualtypname;
                              11317                 :                : 
                              11318                 :             41 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11319                 :             41 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11320                 :                : 
                              11321                 :             41 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              11322                 :                : 
 3176                         11323         [ +  + ]:             41 :     if (dopt->binary_upgrade)
 2388                         11324                 :              2 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
                              11325                 :              2 :                                                  tyinfo->dobj.catId.oid,
                              11326                 :                :                                                  false, false);
                              11327                 :                : 
 3176                         11328                 :             41 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
                              11329                 :                :                       qualtypname);
                              11330                 :                : 
                              11331         [ +  + ]:             41 :     if (dopt->binary_upgrade)
 2239                         11332                 :              2 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11333                 :                :                                         "TYPE", qtypname,
                              11334                 :              2 :                                         tyinfo->dobj.namespace->dobj.name);
                              11335                 :                : 
 2930 sfrost@snowman.net      11336         [ +  - ]:             41 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11337                 :             41 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11338                 :             41 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11339                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11340                 :                :                                   .owner = tyinfo->rolname,
                              11341                 :                :                                   .description = "TYPE",
                              11342                 :                :                                   .section = SECTION_PRE_DATA,
                              11343                 :                :                                   .createStmt = q->data,
                              11344                 :                :                                   .dropStmt = delq->data));
                              11345                 :                : 
                              11346                 :                :     /* Dump Type Comments and Security Labels */
 2930 sfrost@snowman.net      11347         [ +  + ]:             41 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11348                 :             36 :         dumpComment(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11349                 :             36 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11350                 :             36 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11351                 :                : 
                              11352         [ -  + ]:             41 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11353                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11354                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11355                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11356                 :                : 
 2930 sfrost@snowman.net      11357         [ -  + ]:CBC          41 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11358                 :UBC           0 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11359                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11360                 :              0 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11361                 :UNC           0 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11362                 :                : 
 3176 tgl@sss.pgh.pa.us       11363                 :CBC          41 :     destroyPQExpBuffer(q);
                              11364                 :             41 :     destroyPQExpBuffer(delq);
 2239                         11365                 :             41 :     free(qtypname);
                              11366                 :             41 :     free(qualtypname);
 3176                         11367                 :             41 : }
                              11368                 :                : 
                              11369                 :                : /*
                              11370                 :                :  * dumpBaseType
                              11371                 :                :  *    writes out to fout the queries to recreate a user-defined base type
                              11372                 :                :  */
                              11373                 :                : static void
 1159 peter@eisentraut.org    11374                 :            141 : dumpBaseType(Archive *fout, const TypeInfo *tyinfo)
                              11375                 :                : {
 3014 tgl@sss.pgh.pa.us       11376                 :            141 :     DumpOptions *dopt = fout->dopt;
 8010                         11377                 :            141 :     PQExpBuffer q = createPQExpBuffer();
                              11378                 :            141 :     PQExpBuffer delq = createPQExpBuffer();
                              11379                 :            141 :     PQExpBuffer query = createPQExpBuffer();
                              11380                 :                :     PGresult   *res;
                              11381                 :                :     char       *qtypname;
                              11382                 :                :     char       *qualtypname;
                              11383                 :                :     char       *typlen;
                              11384                 :                :     char       *typinput;
                              11385                 :                :     char       *typoutput;
                              11386                 :                :     char       *typreceive;
                              11387                 :                :     char       *typsend;
                              11388                 :                :     char       *typmodin;
                              11389                 :                :     char       *typmodout;
                              11390                 :                :     char       *typanalyze;
                              11391                 :                :     char       *typsubscript;
                              11392                 :                :     Oid         typreceiveoid;
                              11393                 :                :     Oid         typsendoid;
                              11394                 :                :     Oid         typmodinoid;
                              11395                 :                :     Oid         typmodoutoid;
                              11396                 :                :     Oid         typanalyzeoid;
                              11397                 :                :     Oid         typsubscriptoid;
                              11398                 :                :     char       *typcategory;
                              11399                 :                :     char       *typispreferred;
                              11400                 :                :     char       *typdelim;
                              11401                 :                :     char       *typbyval;
                              11402                 :                :     char       *typalign;
                              11403                 :                :     char       *typstorage;
                              11404                 :                :     char       *typcollatable;
                              11405                 :                :     char       *typdefault;
 6627                         11406                 :            141 :     bool        typdefault_is_literal = false;
                              11407                 :                : 
  860                         11408         [ +  + ]:            141 :     if (!fout->is_prepared[PREPQUERY_DUMPBASETYPE])
                              11409                 :                :     {
                              11410                 :                :         /* Set up query for type-specific details */
 1225                         11411                 :             42 :         appendPQExpBufferStr(query,
                              11412                 :                :                              "PREPARE dumpBaseType(pg_catalog.oid) AS\n"
                              11413                 :                :                              "SELECT typlen, "
                              11414                 :                :                              "typinput, typoutput, typreceive, typsend, "
                              11415                 :                :                              "typreceive::pg_catalog.oid AS typreceiveoid, "
                              11416                 :                :                              "typsend::pg_catalog.oid AS typsendoid, "
                              11417                 :                :                              "typanalyze, "
                              11418                 :                :                              "typanalyze::pg_catalog.oid AS typanalyzeoid, "
                              11419                 :                :                              "typdelim, typbyval, typalign, typstorage, "
                              11420                 :                :                              "typmodin, typmodout, "
                              11421                 :                :                              "typmodin::pg_catalog.oid AS typmodinoid, "
                              11422                 :                :                              "typmodout::pg_catalog.oid AS typmodoutoid, "
                              11423                 :                :                              "typcategory, typispreferred, "
                              11424                 :                :                              "(typcollation <> 0) AS typcollatable, "
                              11425                 :                :                              "pg_catalog.pg_get_expr(typdefaultbin, 0) AS typdefaultbin, typdefault, ");
                              11426                 :                : 
  860                         11427         [ +  - ]:             42 :         if (fout->remoteVersion >= 140000)
                              11428                 :             42 :             appendPQExpBufferStr(query,
                              11429                 :                :                                  "typsubscript, "
                              11430                 :                :                                  "typsubscript::pg_catalog.oid AS typsubscriptoid ");
                              11431                 :                :         else
  860 tgl@sss.pgh.pa.us       11432                 :UBC           0 :             appendPQExpBufferStr(query,
                              11433                 :                :                                  "'-' AS typsubscript, 0 AS typsubscriptoid ");
                              11434                 :                : 
  860 tgl@sss.pgh.pa.us       11435                 :CBC          42 :         appendPQExpBufferStr(query, "FROM pg_catalog.pg_type "
                              11436                 :                :                              "WHERE oid = $1");
                              11437                 :                : 
                              11438                 :             42 :         ExecuteSqlStatement(fout, query->data);
                              11439                 :                : 
                              11440                 :             42 :         fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true;
                              11441                 :                :     }
                              11442                 :                : 
                              11443                 :            141 :     printfPQExpBuffer(query,
                              11444                 :                :                       "EXECUTE dumpBaseType('%u')",
 1225                         11445                 :            141 :                       tyinfo->dobj.catId.oid);
                              11446                 :                : 
 4441 rhaas@postgresql.org    11447                 :            141 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              11448                 :                : 
 8010 tgl@sss.pgh.pa.us       11449                 :            141 :     typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
                              11450                 :            141 :     typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
                              11451                 :            141 :     typoutput = PQgetvalue(res, 0, PQfnumber(res, "typoutput"));
 7647                         11452                 :            141 :     typreceive = PQgetvalue(res, 0, PQfnumber(res, "typreceive"));
                              11453                 :            141 :     typsend = PQgetvalue(res, 0, PQfnumber(res, "typsend"));
 6315                         11454                 :            141 :     typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin"));
                              11455                 :            141 :     typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout"));
 7367                         11456                 :            141 :     typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze"));
 1222                         11457                 :            141 :     typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript"));
 7435                         11458                 :            141 :     typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid")));
                              11459                 :            141 :     typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid")));
 6315                         11460                 :            141 :     typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid")));
                              11461                 :            141 :     typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid")));
 7367                         11462                 :            141 :     typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid")));
 1222                         11463                 :            141 :     typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid")));
 5737                         11464                 :            141 :     typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory"));
                              11465                 :            141 :     typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred"));
 8010                         11466                 :            141 :     typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim"));
                              11467                 :            141 :     typbyval = PQgetvalue(res, 0, PQfnumber(res, "typbyval"));
                              11468                 :            141 :     typalign = PQgetvalue(res, 0, PQfnumber(res, "typalign"));
                              11469                 :            141 :     typstorage = PQgetvalue(res, 0, PQfnumber(res, "typstorage"));
 4793 peter_e@gmx.net         11470                 :            141 :     typcollatable = PQgetvalue(res, 0, PQfnumber(res, "typcollatable"));
 6627 tgl@sss.pgh.pa.us       11471         [ -  + ]:            141 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
 6627 tgl@sss.pgh.pa.us       11472                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
 6627 tgl@sss.pgh.pa.us       11473         [ +  + ]:CBC         141 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              11474                 :                :     {
                              11475                 :             46 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6402 bruce@momjian.us        11476                 :             46 :         typdefault_is_literal = true;   /* it needs quotes */
                              11477                 :                :     }
                              11478                 :                :     else
 6627 tgl@sss.pgh.pa.us       11479                 :             95 :         typdefault = NULL;
                              11480                 :                : 
 4144                         11481                 :            141 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11482                 :            141 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11483                 :                : 
                              11484                 :                :     /*
                              11485                 :                :      * The reason we include CASCADE is that the circular dependency between
                              11486                 :                :      * the type and its I/O functions makes it impossible to drop the type any
                              11487                 :                :      * other way.
                              11488                 :                :      */
                              11489                 :            141 :     appendPQExpBuffer(delq, "DROP TYPE %s CASCADE;\n", qualtypname);
                              11490                 :                : 
                              11491                 :                :     /*
                              11492                 :                :      * We might already have a shell type, but setting pg_type_oid is
                              11493                 :                :      * harmless, and in any case we'd better set the array type OID.
                              11494                 :                :      */
 3470 alvherre@alvh.no-ip.    11495         [ +  + ]:            141 :     if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    11496                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2388 tgl@sss.pgh.pa.us       11497                 :              8 :                                                  tyinfo->dobj.catId.oid,
                              11498                 :                :                                                  false, false);
                              11499                 :                : 
 8010                         11500                 :            141 :     appendPQExpBuffer(q,
                              11501                 :                :                       "CREATE TYPE %s (\n"
                              11502                 :                :                       "    INTERNALLENGTH = %s",
                              11503                 :                :                       qualtypname,
 7935 peter_e@gmx.net         11504         [ +  + ]:            141 :                       (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
                              11505                 :                : 
                              11506                 :                :     /* regproc result is sufficiently quoted already */
 2741 tgl@sss.pgh.pa.us       11507                 :            141 :     appendPQExpBuffer(q, ",\n    INPUT = %s", typinput);
                              11508                 :            141 :     appendPQExpBuffer(q, ",\n    OUTPUT = %s", typoutput);
                              11509         [ +  + ]:            141 :     if (OidIsValid(typreceiveoid))
                              11510                 :             68 :         appendPQExpBuffer(q, ",\n    RECEIVE = %s", typreceive);
                              11511         [ +  + ]:            141 :     if (OidIsValid(typsendoid))
                              11512                 :             68 :         appendPQExpBuffer(q, ",\n    SEND = %s", typsend);
                              11513         [ +  + ]:            141 :     if (OidIsValid(typmodinoid))
                              11514                 :             15 :         appendPQExpBuffer(q, ",\n    TYPMOD_IN = %s", typmodin);
                              11515         [ +  + ]:            141 :     if (OidIsValid(typmodoutoid))
                              11516                 :             15 :         appendPQExpBuffer(q, ",\n    TYPMOD_OUT = %s", typmodout);
                              11517         [ +  + ]:            141 :     if (OidIsValid(typanalyzeoid))
                              11518                 :              1 :         appendPQExpBuffer(q, ",\n    ANALYZE = %s", typanalyze);
                              11519                 :                : 
 4793 peter_e@gmx.net         11520         [ +  + ]:            141 :     if (strcmp(typcollatable, "t") == 0)
 3800 heikki.linnakangas@i    11521                 :             10 :         appendPQExpBufferStr(q, ",\n    COLLATABLE = true");
                              11522                 :                : 
 8010 tgl@sss.pgh.pa.us       11523         [ +  + ]:            141 :     if (typdefault != NULL)
                              11524                 :                :     {
 3800 heikki.linnakangas@i    11525                 :             46 :         appendPQExpBufferStr(q, ",\n    DEFAULT = ");
 6627 tgl@sss.pgh.pa.us       11526         [ +  - ]:             46 :         if (typdefault_is_literal)
 6531                         11527                 :             46 :             appendStringLiteralAH(q, typdefault, fout);
                              11528                 :                :         else
 6627 tgl@sss.pgh.pa.us       11529                 :UBC           0 :             appendPQExpBufferStr(q, typdefault);
                              11530                 :                :     }
                              11531                 :                : 
 1222 tgl@sss.pgh.pa.us       11532         [ +  + ]:CBC         141 :     if (OidIsValid(typsubscriptoid))
                              11533                 :             13 :         appendPQExpBuffer(q, ",\n    SUBSCRIPT = %s", typsubscript);
                              11534                 :                : 
 5226 bruce@momjian.us        11535         [ +  + ]:            141 :     if (OidIsValid(tyinfo->typelem))
  949 tgl@sss.pgh.pa.us       11536                 :             12 :         appendPQExpBuffer(q, ",\n    ELEMENT = %s",
                              11537                 :             12 :                           getFormattedTypeName(fout, tyinfo->typelem,
                              11538                 :                :                                                zeroIsError));
                              11539                 :                : 
 5737                         11540         [ +  + ]:            141 :     if (strcmp(typcategory, "U") != 0)
                              11541                 :                :     {
 3800 heikki.linnakangas@i    11542                 :             55 :         appendPQExpBufferStr(q, ",\n    CATEGORY = ");
 5737 tgl@sss.pgh.pa.us       11543                 :             55 :         appendStringLiteralAH(q, typcategory, fout);
                              11544                 :                :     }
                              11545                 :                : 
                              11546         [ +  + ]:            141 :     if (strcmp(typispreferred, "t") == 0)
 3800 heikki.linnakangas@i    11547                 :             13 :         appendPQExpBufferStr(q, ",\n    PREFERRED = true");
                              11548                 :                : 
 7647 tgl@sss.pgh.pa.us       11549   [ +  -  +  + ]:            141 :     if (typdelim && strcmp(typdelim, ",") != 0)
                              11550                 :                :     {
 3800 heikki.linnakangas@i    11551                 :              1 :         appendPQExpBufferStr(q, ",\n    DELIMITER = ");
 6531 tgl@sss.pgh.pa.us       11552                 :              1 :         appendStringLiteralAH(q, typdelim, fout);
                              11553                 :                :     }
                              11554                 :                : 
 1502                         11555         [ +  + ]:            141 :     if (*typalign == TYPALIGN_CHAR)
 3800 heikki.linnakangas@i    11556                 :              4 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = char");
 1502 tgl@sss.pgh.pa.us       11557         [ +  + ]:            137 :     else if (*typalign == TYPALIGN_SHORT)
 3800 heikki.linnakangas@i    11558                 :              2 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int2");
 1502 tgl@sss.pgh.pa.us       11559         [ +  + ]:            135 :     else if (*typalign == TYPALIGN_INT)
 3800 heikki.linnakangas@i    11560                 :            100 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = int4");
 1502 tgl@sss.pgh.pa.us       11561         [ +  - ]:             35 :     else if (*typalign == TYPALIGN_DOUBLE)
 3800 heikki.linnakangas@i    11562                 :             35 :         appendPQExpBufferStr(q, ",\n    ALIGNMENT = double");
                              11563                 :                : 
 1502 tgl@sss.pgh.pa.us       11564         [ +  + ]:            141 :     if (*typstorage == TYPSTORAGE_PLAIN)
 3800 heikki.linnakangas@i    11565                 :            116 :         appendPQExpBufferStr(q, ",\n    STORAGE = plain");
 1502 tgl@sss.pgh.pa.us       11566         [ -  + ]:             25 :     else if (*typstorage == TYPSTORAGE_EXTERNAL)
 3800 heikki.linnakangas@i    11567                 :UBC           0 :         appendPQExpBufferStr(q, ",\n    STORAGE = external");
 1502 tgl@sss.pgh.pa.us       11568         [ +  + ]:CBC          25 :     else if (*typstorage == TYPSTORAGE_EXTENDED)
 3800 heikki.linnakangas@i    11569                 :             22 :         appendPQExpBufferStr(q, ",\n    STORAGE = extended");
 1502 tgl@sss.pgh.pa.us       11570         [ +  - ]:              3 :     else if (*typstorage == TYPSTORAGE_MAIN)
 3800 heikki.linnakangas@i    11571                 :              3 :         appendPQExpBufferStr(q, ",\n    STORAGE = main");
                              11572                 :                : 
 8010 tgl@sss.pgh.pa.us       11573         [ +  + ]:            141 :     if (strcmp(typbyval, "t") == 0)
 3800 heikki.linnakangas@i    11574                 :             79 :         appendPQExpBufferStr(q, ",\n    PASSEDBYVALUE");
                              11575                 :                : 
                              11576                 :            141 :     appendPQExpBufferStr(q, "\n);\n");
                              11577                 :                : 
 3470 alvherre@alvh.no-ip.    11578         [ +  + ]:            141 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       11579                 :              8 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11580                 :                :                                         "TYPE", qtypname,
                              11581                 :              8 :                                         tyinfo->dobj.namespace->dobj.name);
                              11582                 :                : 
 2930 sfrost@snowman.net      11583         [ +  - ]:            141 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11584                 :            141 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11585                 :            141 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11586                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11587                 :                :                                   .owner = tyinfo->rolname,
                              11588                 :                :                                   .description = "TYPE",
                              11589                 :                :                                   .section = SECTION_PRE_DATA,
                              11590                 :                :                                   .createStmt = q->data,
                              11591                 :                :                                   .dropStmt = delq->data));
                              11592                 :                : 
                              11593                 :                :     /* Dump Type Comments and Security Labels */
 2930 sfrost@snowman.net      11594         [ +  + ]:            141 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11595                 :            106 :         dumpComment(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11596                 :            106 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11597                 :            106 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11598                 :                : 
                              11599         [ -  + ]:            141 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11600                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11601                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11602                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11603                 :                : 
 2930 sfrost@snowman.net      11604         [ +  + ]:CBC         141 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11605                 :             36 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11606                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11607                 :             36 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11608                 :GNC          36 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11609                 :                : 
 8853 bruce@momjian.us        11610                 :CBC         141 :     PQclear(res);
 8010 tgl@sss.pgh.pa.us       11611                 :            141 :     destroyPQExpBuffer(q);
                              11612                 :            141 :     destroyPQExpBuffer(delq);
 8290                         11613                 :            141 :     destroyPQExpBuffer(query);
 2239                         11614                 :            141 :     free(qtypname);
                              11615                 :            141 :     free(qualtypname);
 8853 bruce@momjian.us        11616                 :            141 : }
                              11617                 :                : 
                              11618                 :                : /*
                              11619                 :                :  * dumpDomain
                              11620                 :                :  *    writes out to fout the queries to recreate a user-defined domain
                              11621                 :                :  */
                              11622                 :                : static void
 1159 peter@eisentraut.org    11623                 :            131 : dumpDomain(Archive *fout, const TypeInfo *tyinfo)
                              11624                 :                : {
 3014 tgl@sss.pgh.pa.us       11625                 :            131 :     DumpOptions *dopt = fout->dopt;
 8045 bruce@momjian.us        11626                 :            131 :     PQExpBuffer q = createPQExpBuffer();
                              11627                 :            131 :     PQExpBuffer delq = createPQExpBuffer();
                              11628                 :            131 :     PQExpBuffer query = createPQExpBuffer();
                              11629                 :                :     PGresult   *res;
                              11630                 :                :     int         i;
                              11631                 :                :     char       *qtypname;
                              11632                 :                :     char       *qualtypname;
                              11633                 :                :     char       *typnotnull;
                              11634                 :                :     char       *typdefn;
                              11635                 :                :     char       *typdefault;
                              11636                 :                :     Oid         typcollation;
 6627 tgl@sss.pgh.pa.us       11637                 :            131 :     bool        typdefault_is_literal = false;
                              11638                 :                : 
  860                         11639         [ +  + ]:            131 :     if (!fout->is_prepared[PREPQUERY_DUMPDOMAIN])
                              11640                 :                :     {
                              11641                 :                :         /* Set up query for domain-specific details */
                              11642                 :             41 :         appendPQExpBufferStr(query,
                              11643                 :                :                              "PREPARE dumpDomain(pg_catalog.oid) AS\n");
                              11644                 :                : 
  852                         11645                 :             41 :         appendPQExpBufferStr(query, "SELECT t.typnotnull, "
                              11646                 :                :                              "pg_catalog.format_type(t.typbasetype, t.typtypmod) AS typdefn, "
                              11647                 :                :                              "pg_catalog.pg_get_expr(t.typdefaultbin, 'pg_catalog.pg_type'::pg_catalog.regclass) AS typdefaultbin, "
                              11648                 :                :                              "t.typdefault, "
                              11649                 :                :                              "CASE WHEN t.typcollation <> u.typcollation "
                              11650                 :                :                              "THEN t.typcollation ELSE 0 END AS typcollation "
                              11651                 :                :                              "FROM pg_catalog.pg_type t "
                              11652                 :                :                              "LEFT JOIN pg_catalog.pg_type u ON (t.typbasetype = u.oid) "
                              11653                 :                :                              "WHERE t.oid = $1");
                              11654                 :                : 
  860                         11655                 :             41 :         ExecuteSqlStatement(fout, query->data);
                              11656                 :                : 
                              11657                 :             41 :         fout->is_prepared[PREPQUERY_DUMPDOMAIN] = true;
                              11658                 :                :     }
                              11659                 :                : 
                              11660                 :            131 :     printfPQExpBuffer(query,
                              11661                 :                :                       "EXECUTE dumpDomain('%u')",
                              11662                 :            131 :                       tyinfo->dobj.catId.oid);
                              11663                 :                : 
 4441 rhaas@postgresql.org    11664                 :            131 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              11665                 :                : 
 8010 tgl@sss.pgh.pa.us       11666                 :            131 :     typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
                              11667                 :            131 :     typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
 6627                         11668         [ +  + ]:            131 :     if (!PQgetisnull(res, 0, PQfnumber(res, "typdefaultbin")))
                              11669                 :             41 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefaultbin"));
                              11670         [ -  + ]:             90 :     else if (!PQgetisnull(res, 0, PQfnumber(res, "typdefault")))
                              11671                 :                :     {
 7992 tgl@sss.pgh.pa.us       11672                 :UBC           0 :         typdefault = PQgetvalue(res, 0, PQfnumber(res, "typdefault"));
 6402 bruce@momjian.us        11673                 :              0 :         typdefault_is_literal = true;   /* it needs quotes */
                              11674                 :                :     }
                              11675                 :                :     else
 6627 tgl@sss.pgh.pa.us       11676                 :CBC          90 :         typdefault = NULL;
 4784                         11677                 :            131 :     typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
                              11678                 :                : 
 3470 alvherre@alvh.no-ip.    11679         [ +  + ]:            131 :     if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    11680                 :             20 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2388 tgl@sss.pgh.pa.us       11681                 :             20 :                                                  tyinfo->dobj.catId.oid,
                              11682                 :                :                                                  true,  /* force array type */
                              11683                 :                :                                                  false);    /* force multirange type */
                              11684                 :                : 
 4144                         11685                 :            131 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11686                 :            131 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11687                 :                : 
 8045 bruce@momjian.us        11688                 :            131 :     appendPQExpBuffer(q,
                              11689                 :                :                       "CREATE DOMAIN %s AS %s",
                              11690                 :                :                       qualtypname,
                              11691                 :                :                       typdefn);
                              11692                 :                : 
                              11693                 :                :     /* Print collation only if different from base type's collation */
 4784 tgl@sss.pgh.pa.us       11694         [ +  + ]:            131 :     if (OidIsValid(typcollation))
                              11695                 :                :     {
                              11696                 :                :         CollInfo   *coll;
                              11697                 :                : 
                              11698                 :             36 :         coll = findCollationByOid(typcollation);
                              11699         [ +  - ]:             36 :         if (coll)
 2239                         11700                 :             36 :             appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll));
                              11701                 :                :     }
                              11702                 :                : 
 8010                         11703         [ +  + ]:            131 :     if (typnotnull[0] == 't')
 3800 heikki.linnakangas@i    11704                 :             15 :         appendPQExpBufferStr(q, " NOT NULL");
                              11705                 :                : 
 6627 tgl@sss.pgh.pa.us       11706         [ +  + ]:            131 :     if (typdefault != NULL)
                              11707                 :                :     {
 3800 heikki.linnakangas@i    11708                 :             41 :         appendPQExpBufferStr(q, " DEFAULT ");
 6627 tgl@sss.pgh.pa.us       11709         [ -  + ]:             41 :         if (typdefault_is_literal)
 6531 tgl@sss.pgh.pa.us       11710                 :UBC           0 :             appendStringLiteralAH(q, typdefault, fout);
                              11711                 :                :         else
 6627 tgl@sss.pgh.pa.us       11712                 :CBC          41 :             appendPQExpBufferStr(q, typdefault);
                              11713                 :                :     }
                              11714                 :                : 
 7794                         11715                 :            131 :     PQclear(res);
                              11716                 :                : 
                              11717                 :                :     /*
                              11718                 :                :      * Add any CHECK constraints for the domain
                              11719                 :                :      */
 5226 bruce@momjian.us        11720         [ +  + ]:            217 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              11721                 :                :     {
                              11722                 :             86 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
                              11723                 :                : 
 7435 tgl@sss.pgh.pa.us       11724         [ +  - ]:             86 :         if (!domcheck->separate)
                              11725                 :             86 :             appendPQExpBuffer(q, "\n\tCONSTRAINT %s %s",
 6756 bruce@momjian.us        11726                 :             86 :                               fmtId(domcheck->dobj.name), domcheck->condef);
                              11727                 :                :     }
                              11728                 :                : 
 3800 heikki.linnakangas@i    11729                 :            131 :     appendPQExpBufferStr(q, ";\n");
                              11730                 :                : 
 2239 tgl@sss.pgh.pa.us       11731                 :            131 :     appendPQExpBuffer(delq, "DROP DOMAIN %s;\n", qualtypname);
                              11732                 :                : 
 3470 alvherre@alvh.no-ip.    11733         [ +  + ]:            131 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       11734                 :             20 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11735                 :                :                                         "DOMAIN", qtypname,
                              11736                 :             20 :                                         tyinfo->dobj.namespace->dobj.name);
                              11737                 :                : 
 2930 sfrost@snowman.net      11738         [ +  - ]:            131 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11739                 :            131 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11740                 :            131 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11741                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11742                 :                :                                   .owner = tyinfo->rolname,
                              11743                 :                :                                   .description = "DOMAIN",
                              11744                 :                :                                   .section = SECTION_PRE_DATA,
                              11745                 :                :                                   .createStmt = q->data,
                              11746                 :                :                                   .dropStmt = delq->data));
                              11747                 :                : 
                              11748                 :                :     /* Dump Domain Comments and Security Labels */
 2930 sfrost@snowman.net      11749         [ -  + ]:            131 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11750                 :UBC           0 :         dumpComment(fout, "DOMAIN", qtypname,
 2930 sfrost@snowman.net      11751                 :              0 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11752                 :              0 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11753                 :                : 
 2930 sfrost@snowman.net      11754         [ -  + ]:CBC         131 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11755                 :UBC           0 :         dumpSecLabel(fout, "DOMAIN", qtypname,
 2930 sfrost@snowman.net      11756                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11757                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11758                 :                : 
 2930 sfrost@snowman.net      11759         [ +  + ]:CBC         131 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11760                 :             36 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11761                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11762                 :             36 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11763                 :GNC          36 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11764                 :                : 
                              11765                 :                :     /* Dump any per-constraint comments */
 3400 alvherre@alvh.no-ip.    11766         [ +  + ]:CBC         217 :     for (i = 0; i < tyinfo->nDomChecks; i++)
                              11767                 :                :     {
                              11768                 :             86 :         ConstraintInfo *domcheck = &(tyinfo->domChecks[i]);
 2239 tgl@sss.pgh.pa.us       11769                 :             86 :         PQExpBuffer conprefix = createPQExpBuffer();
                              11770                 :                : 
                              11771                 :             86 :         appendPQExpBuffer(conprefix, "CONSTRAINT %s ON DOMAIN",
 3400 alvherre@alvh.no-ip.    11772                 :             86 :                           fmtId(domcheck->dobj.name));
                              11773                 :                : 
  529 tgl@sss.pgh.pa.us       11774         [ +  + ]:             86 :         if (domcheck->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239                         11775                 :             36 :             dumpComment(fout, conprefix->data, qtypname,
 2930 sfrost@snowman.net      11776                 :             36 :                         tyinfo->dobj.namespace->dobj.name,
                              11777                 :             36 :                         tyinfo->rolname,
                              11778                 :             36 :                         domcheck->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11779                 :                : 
 2239 tgl@sss.pgh.pa.us       11780                 :             86 :         destroyPQExpBuffer(conprefix);
                              11781                 :                :     }
                              11782                 :                : 
 8010                         11783                 :            131 :     destroyPQExpBuffer(q);
                              11784                 :            131 :     destroyPQExpBuffer(delq);
                              11785                 :            131 :     destroyPQExpBuffer(query);
 2239                         11786                 :            131 :     free(qtypname);
                              11787                 :            131 :     free(qualtypname);
 8045 bruce@momjian.us        11788                 :            131 : }
                              11789                 :                : 
                              11790                 :                : /*
                              11791                 :                :  * dumpCompositeType
                              11792                 :                :  *    writes out to fout the queries to recreate a user-defined stand-alone
                              11793                 :                :  *    composite type
                              11794                 :                :  */
                              11795                 :                : static void
 1159 peter@eisentraut.org    11796                 :            134 : dumpCompositeType(Archive *fout, const TypeInfo *tyinfo)
                              11797                 :                : {
 3014 tgl@sss.pgh.pa.us       11798                 :            134 :     DumpOptions *dopt = fout->dopt;
 7913 bruce@momjian.us        11799                 :            134 :     PQExpBuffer q = createPQExpBuffer();
 4712 heikki.linnakangas@i    11800                 :            134 :     PQExpBuffer dropped = createPQExpBuffer();
 7913 bruce@momjian.us        11801                 :            134 :     PQExpBuffer delq = createPQExpBuffer();
                              11802                 :            134 :     PQExpBuffer query = createPQExpBuffer();
                              11803                 :                :     PGresult   *res;
                              11804                 :                :     char       *qtypname;
                              11805                 :                :     char       *qualtypname;
                              11806                 :                :     int         ntups;
                              11807                 :                :     int         i_attname;
                              11808                 :                :     int         i_atttypdefn;
                              11809                 :                :     int         i_attlen;
                              11810                 :                :     int         i_attalign;
                              11811                 :                :     int         i_attisdropped;
                              11812                 :                :     int         i_attcollation;
                              11813                 :                :     int         i;
                              11814                 :                :     int         actual_atts;
                              11815                 :                : 
  860 tgl@sss.pgh.pa.us       11816         [ +  + ]:            134 :     if (!fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE])
                              11817                 :                :     {
                              11818                 :                :         /*
                              11819                 :                :          * Set up query for type-specific details.
                              11820                 :                :          *
                              11821                 :                :          * Since we only want to dump COLLATE clauses for attributes whose
                              11822                 :                :          * collation is different from their type's default, we use a CASE
                              11823                 :                :          * here to suppress uninteresting attcollations cheaply.  atttypid
                              11824                 :                :          * will be 0 for dropped columns; collation does not matter for those.
                              11825                 :                :          */
                              11826                 :             59 :         appendPQExpBufferStr(query,
                              11827                 :                :                              "PREPARE dumpCompositeType(pg_catalog.oid) AS\n"
                              11828                 :                :                              "SELECT a.attname, a.attnum, "
                              11829                 :                :                              "pg_catalog.format_type(a.atttypid, a.atttypmod) AS atttypdefn, "
                              11830                 :                :                              "a.attlen, a.attalign, a.attisdropped, "
                              11831                 :                :                              "CASE WHEN a.attcollation <> at.typcollation "
                              11832                 :                :                              "THEN a.attcollation ELSE 0 END AS attcollation "
                              11833                 :                :                              "FROM pg_catalog.pg_type ct "
                              11834                 :                :                              "JOIN pg_catalog.pg_attribute a ON a.attrelid = ct.typrelid "
                              11835                 :                :                              "LEFT JOIN pg_catalog.pg_type at ON at.oid = a.atttypid "
                              11836                 :                :                              "WHERE ct.oid = $1 "
                              11837                 :                :                              "ORDER BY a.attnum");
                              11838                 :                : 
                              11839                 :             59 :         ExecuteSqlStatement(fout, query->data);
                              11840                 :                : 
                              11841                 :             59 :         fout->is_prepared[PREPQUERY_DUMPCOMPOSITETYPE] = true;
                              11842                 :                :     }
                              11843                 :                : 
                              11844                 :            134 :     printfPQExpBuffer(query,
                              11845                 :                :                       "EXECUTE dumpCompositeType('%u')",
                              11846                 :            134 :                       tyinfo->dobj.catId.oid);
                              11847                 :                : 
 4450 rhaas@postgresql.org    11848                 :            134 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              11849                 :                : 
 7913 bruce@momjian.us        11850                 :            134 :     ntups = PQntuples(res);
                              11851                 :                : 
 7899 tgl@sss.pgh.pa.us       11852                 :            134 :     i_attname = PQfnumber(res, "attname");
                              11853                 :            134 :     i_atttypdefn = PQfnumber(res, "atttypdefn");
 4712 heikki.linnakangas@i    11854                 :            134 :     i_attlen = PQfnumber(res, "attlen");
                              11855                 :            134 :     i_attalign = PQfnumber(res, "attalign");
                              11856                 :            134 :     i_attisdropped = PQfnumber(res, "attisdropped");
 4746 tgl@sss.pgh.pa.us       11857                 :            134 :     i_attcollation = PQfnumber(res, "attcollation");
                              11858                 :                : 
 3470 alvherre@alvh.no-ip.    11859         [ +  + ]:            134 :     if (dopt->binary_upgrade)
                              11860                 :                :     {
 4450 rhaas@postgresql.org    11861                 :             18 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2388 tgl@sss.pgh.pa.us       11862                 :             18 :                                                  tyinfo->dobj.catId.oid,
                              11863                 :                :                                                  false, false);
 3467                         11864                 :             18 :         binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid, false);
                              11865                 :                :     }
                              11866                 :                : 
 4144                         11867                 :            134 :     qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 2239                         11868                 :            134 :     qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo));
                              11869                 :                : 
 7899                         11870                 :            134 :     appendPQExpBuffer(q, "CREATE TYPE %s AS (",
                              11871                 :                :                       qualtypname);
                              11872                 :                : 
 4712 heikki.linnakangas@i    11873                 :            134 :     actual_atts = 0;
 7913 bruce@momjian.us        11874         [ +  + ]:            424 :     for (i = 0; i < ntups; i++)
                              11875                 :                :     {
                              11876                 :                :         char       *attname;
                              11877                 :                :         char       *atttypdefn;
                              11878                 :                :         char       *attlen;
                              11879                 :                :         char       *attalign;
                              11880                 :                :         bool        attisdropped;
                              11881                 :                :         Oid         attcollation;
                              11882                 :                : 
 7899 tgl@sss.pgh.pa.us       11883                 :            290 :         attname = PQgetvalue(res, i, i_attname);
                              11884                 :            290 :         atttypdefn = PQgetvalue(res, i, i_atttypdefn);
 4712 heikki.linnakangas@i    11885                 :            290 :         attlen = PQgetvalue(res, i, i_attlen);
                              11886                 :            290 :         attalign = PQgetvalue(res, i, i_attalign);
                              11887                 :            290 :         attisdropped = (PQgetvalue(res, i, i_attisdropped)[0] == 't');
 4746 tgl@sss.pgh.pa.us       11888                 :            290 :         attcollation = atooid(PQgetvalue(res, i, i_attcollation));
                              11889                 :                : 
 3470 alvherre@alvh.no-ip.    11890   [ +  +  +  + ]:            290 :         if (attisdropped && !dopt->binary_upgrade)
 4712 heikki.linnakangas@i    11891                 :              8 :             continue;
                              11892                 :                : 
                              11893                 :                :         /* Format properly if not first attr */
                              11894         [ +  + ]:            282 :         if (actual_atts++ > 0)
 3800                         11895                 :            148 :             appendPQExpBufferChar(q, ',');
                              11896                 :            282 :         appendPQExpBufferStr(q, "\n\t");
                              11897                 :                : 
 4712                         11898         [ +  + ]:            282 :         if (!attisdropped)
                              11899                 :                :         {
                              11900                 :            280 :             appendPQExpBuffer(q, "%s %s", fmtId(attname), atttypdefn);
                              11901                 :                : 
                              11902                 :                :             /* Add collation if not default for the column type */
                              11903         [ -  + ]:            280 :             if (OidIsValid(attcollation))
                              11904                 :                :             {
                              11905                 :                :                 CollInfo   *coll;
                              11906                 :                : 
 4712 heikki.linnakangas@i    11907                 :UBC           0 :                 coll = findCollationByOid(attcollation);
                              11908         [ #  # ]:              0 :                 if (coll)
 2239 tgl@sss.pgh.pa.us       11909                 :              0 :                     appendPQExpBuffer(q, " COLLATE %s",
                              11910                 :              0 :                                       fmtQualifiedDumpable(coll));
                              11911                 :                :             }
                              11912                 :                :         }
                              11913                 :                :         else
                              11914                 :                :         {
                              11915                 :                :             /*
                              11916                 :                :              * This is a dropped attribute and we're in binary_upgrade mode.
                              11917                 :                :              * Insert a placeholder for it in the CREATE TYPE command, and set
                              11918                 :                :              * length and alignment with direct UPDATE to the catalogs
                              11919                 :                :              * afterwards. See similar code in dumpTableSchema().
                              11920                 :                :              */
 4712 heikki.linnakangas@i    11921                 :CBC           2 :             appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
                              11922                 :                : 
                              11923                 :                :             /* stash separately for insertion after the CREATE TYPE */
 3800                         11924                 :              2 :             appendPQExpBufferStr(dropped,
                              11925                 :                :                                  "\n-- For binary upgrade, recreate dropped column.\n");
 4712                         11926                 :              2 :             appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
                              11927                 :                :                               "SET attlen = %s, "
                              11928                 :                :                               "attalign = '%s', attbyval = false\n"
                              11929                 :                :                               "WHERE attname = ", attlen, attalign);
                              11930                 :              2 :             appendStringLiteralAH(dropped, attname, fout);
 3800                         11931                 :              2 :             appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
 2239 tgl@sss.pgh.pa.us       11932                 :              2 :             appendStringLiteralAH(dropped, qualtypname, fout);
 3800 heikki.linnakangas@i    11933                 :              2 :             appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
                              11934                 :                : 
 4712                         11935                 :              2 :             appendPQExpBuffer(dropped, "ALTER TYPE %s ",
                              11936                 :                :                               qualtypname);
                              11937                 :              2 :             appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                              11938                 :                :                               fmtId(attname));
                              11939                 :                :         }
                              11940                 :                :     }
 3800                         11941                 :            134 :     appendPQExpBufferStr(q, "\n);\n");
 4712                         11942                 :            134 :     appendPQExpBufferStr(q, dropped->data);
                              11943                 :                : 
 2239 tgl@sss.pgh.pa.us       11944                 :            134 :     appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname);
                              11945                 :                : 
 3470 alvherre@alvh.no-ip.    11946         [ +  + ]:            134 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       11947                 :             18 :         binary_upgrade_extension_member(q, &tyinfo->dobj,
                              11948                 :                :                                         "TYPE", qtypname,
                              11949                 :             18 :                                         tyinfo->dobj.namespace->dobj.name);
                              11950                 :                : 
 2930 sfrost@snowman.net      11951         [ +  + ]:            134 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              11952                 :            117 :         ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    11953                 :            117 :                      ARCHIVE_OPTS(.tag = tyinfo->dobj.name,
                              11954                 :                :                                   .namespace = tyinfo->dobj.namespace->dobj.name,
                              11955                 :                :                                   .owner = tyinfo->rolname,
                              11956                 :                :                                   .description = "TYPE",
                              11957                 :                :                                   .section = SECTION_PRE_DATA,
                              11958                 :                :                                   .createStmt = q->data,
                              11959                 :                :                                   .dropStmt = delq->data));
                              11960                 :                : 
                              11961                 :                : 
                              11962                 :                :     /* Dump Type Comments and Security Labels */
 2930 sfrost@snowman.net      11963         [ +  + ]:            134 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       11964                 :             36 :         dumpComment(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11965                 :             36 :                     tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11966                 :             36 :                     tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11967                 :                : 
                              11968         [ -  + ]:            134 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       11969                 :UBC           0 :         dumpSecLabel(fout, "TYPE", qtypname,
 2930 sfrost@snowman.net      11970                 :              0 :                      tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                              11971                 :              0 :                      tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
                              11972                 :                : 
 2930 sfrost@snowman.net      11973         [ +  + ]:CBC         134 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       11974                 :             18 :         dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
                              11975                 :                :                 qtypname, NULL,
 2930 sfrost@snowman.net      11976                 :             18 :                 tyinfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       11977                 :GNC          18 :                 NULL, tyinfo->rolname, &tyinfo->dacl);
                              11978                 :                : 
                              11979                 :                :     /* Dump any per-column comments */
  836 tgl@sss.pgh.pa.us       11980         [ +  + ]:CBC         134 :     if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              11981                 :             36 :         dumpCompositeTypeColComments(fout, tyinfo, res);
                              11982                 :                : 
 7435                         11983                 :            134 :     PQclear(res);
                              11984                 :            134 :     destroyPQExpBuffer(q);
 4712 heikki.linnakangas@i    11985                 :            134 :     destroyPQExpBuffer(dropped);
 7435 tgl@sss.pgh.pa.us       11986                 :            134 :     destroyPQExpBuffer(delq);
                              11987                 :            134 :     destroyPQExpBuffer(query);
 2239                         11988                 :            134 :     free(qtypname);
                              11989                 :            134 :     free(qualtypname);
 5379                         11990                 :            134 : }
                              11991                 :                : 
                              11992                 :                : /*
                              11993                 :                :  * dumpCompositeTypeColComments
                              11994                 :                :  *    writes out to fout the queries to recreate comments on the columns of
                              11995                 :                :  *    a user-defined stand-alone composite type.
                              11996                 :                :  *
                              11997                 :                :  * The caller has already made a query to collect the names and attnums
                              11998                 :                :  * of the type's columns, so we just pass that result into here rather
                              11999                 :                :  * than reading them again.
                              12000                 :                :  */
                              12001                 :                : static void
  836                         12002                 :             36 : dumpCompositeTypeColComments(Archive *fout, const TypeInfo *tyinfo,
                              12003                 :                :                              PGresult *res)
                              12004                 :                : {
                              12005                 :                :     CommentItem *comments;
                              12006                 :                :     int         ncomments;
                              12007                 :                :     PQExpBuffer query;
                              12008                 :                :     PQExpBuffer target;
                              12009                 :                :     int         i;
                              12010                 :                :     int         ntups;
                              12011                 :                :     int         i_attname;
                              12012                 :                :     int         i_attnum;
                              12013                 :                :     int         i_attisdropped;
                              12014                 :                : 
                              12015                 :                :     /* do nothing, if --no-comments is supplied */
 2271                         12016         [ -  + ]:             36 :     if (fout->dopt->no_comments)
 2271 tgl@sss.pgh.pa.us       12017                 :UBC           0 :         return;
                              12018                 :                : 
                              12019                 :                :     /* Search for comments associated with type's pg_class OID */
  836 tgl@sss.pgh.pa.us       12020                 :CBC          36 :     ncomments = findComments(RelationRelationId, tyinfo->typrelid,
                              12021                 :                :                              &comments);
                              12022                 :                : 
                              12023                 :                :     /* If no comments exist, we're done */
 5379                         12024         [ -  + ]:             36 :     if (ncomments <= 0)
 5379 tgl@sss.pgh.pa.us       12025                 :UBC           0 :         return;
                              12026                 :                : 
                              12027                 :                :     /* Build COMMENT ON statements */
  836 tgl@sss.pgh.pa.us       12028                 :CBC          36 :     query = createPQExpBuffer();
 5379                         12029                 :             36 :     target = createPQExpBuffer();
                              12030                 :                : 
  836                         12031                 :             36 :     ntups = PQntuples(res);
 5379                         12032                 :             36 :     i_attnum = PQfnumber(res, "attnum");
                              12033                 :             36 :     i_attname = PQfnumber(res, "attname");
  836                         12034                 :             36 :     i_attisdropped = PQfnumber(res, "attisdropped");
 5379                         12035         [ +  + ]:             72 :     while (ncomments > 0)
                              12036                 :                :     {
                              12037                 :                :         const char *attname;
                              12038                 :                : 
                              12039                 :             36 :         attname = NULL;
                              12040         [ +  - ]:             36 :         for (i = 0; i < ntups; i++)
                              12041                 :                :         {
  836                         12042         [ +  - ]:             36 :             if (atoi(PQgetvalue(res, i, i_attnum)) == comments->objsubid &&
                              12043         [ +  - ]:             36 :                 PQgetvalue(res, i, i_attisdropped)[0] != 't')
                              12044                 :                :             {
 5379                         12045                 :             36 :                 attname = PQgetvalue(res, i, i_attname);
                              12046                 :             36 :                 break;
                              12047                 :                :             }
                              12048                 :                :         }
                              12049         [ +  - ]:             36 :         if (attname)            /* just in case we don't find it */
                              12050                 :                :         {
                              12051                 :             36 :             const char *descr = comments->descr;
                              12052                 :                : 
                              12053                 :             36 :             resetPQExpBuffer(target);
                              12054                 :             36 :             appendPQExpBuffer(target, "COLUMN %s.",
 5226 bruce@momjian.us        12055                 :             36 :                               fmtId(tyinfo->dobj.name));
 3800 heikki.linnakangas@i    12056                 :             36 :             appendPQExpBufferStr(target, fmtId(attname));
                              12057                 :                : 
 5379 tgl@sss.pgh.pa.us       12058                 :             36 :             resetPQExpBuffer(query);
 2239                         12059                 :             36 :             appendPQExpBuffer(query, "COMMENT ON COLUMN %s.",
                              12060                 :             36 :                               fmtQualifiedDumpable(tyinfo));
                              12061                 :             36 :             appendPQExpBuffer(query, "%s IS ", fmtId(attname));
 5379                         12062                 :             36 :             appendStringLiteralAH(query, descr, fout);
 3800 heikki.linnakangas@i    12063                 :             36 :             appendPQExpBufferStr(query, ";\n");
                              12064                 :                : 
 5379 tgl@sss.pgh.pa.us       12065                 :             36 :             ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    12066                 :             36 :                          ARCHIVE_OPTS(.tag = target->data,
                              12067                 :                :                                       .namespace = tyinfo->dobj.namespace->dobj.name,
                              12068                 :                :                                       .owner = tyinfo->rolname,
                              12069                 :                :                                       .description = "COMMENT",
                              12070                 :                :                                       .section = SECTION_NONE,
                              12071                 :                :                                       .createStmt = query->data,
                              12072                 :                :                                       .deps = &(tyinfo->dobj.dumpId),
                              12073                 :                :                                       .nDeps = 1));
                              12074                 :                :         }
                              12075                 :                : 
 5379 tgl@sss.pgh.pa.us       12076                 :             36 :         comments++;
                              12077                 :             36 :         ncomments--;
                              12078                 :                :     }
                              12079                 :                : 
                              12080                 :             36 :     destroyPQExpBuffer(query);
                              12081                 :             36 :     destroyPQExpBuffer(target);
                              12082                 :                : }
                              12083                 :                : 
                              12084                 :                : /*
                              12085                 :                :  * dumpShellType
                              12086                 :                :  *    writes out to fout the queries to create a shell type
                              12087                 :                :  *
                              12088                 :                :  * We dump a shell definition in advance of the I/O functions for the type.
                              12089                 :                :  */
                              12090                 :                : static void
 1159 peter@eisentraut.org    12091                 :             74 : dumpShellType(Archive *fout, const ShellTypeInfo *stinfo)
                              12092                 :                : {
 3014 tgl@sss.pgh.pa.us       12093                 :             74 :     DumpOptions *dopt = fout->dopt;
                              12094                 :                :     PQExpBuffer q;
                              12095                 :                : 
                              12096                 :                :     /* Do nothing in data-only dump */
  860                         12097         [ +  + ]:             74 :     if (dopt->dataOnly)
 6618                         12098                 :              3 :         return;
                              12099                 :                : 
                              12100                 :             71 :     q = createPQExpBuffer();
                              12101                 :                : 
                              12102                 :                :     /*
                              12103                 :                :      * Note the lack of a DROP command for the shell type; any required DROP
                              12104                 :                :      * is driven off the base type entry, instead.  This interacts with
                              12105                 :                :      * _printTocEntry()'s use of the presence of a DROP command to decide
                              12106                 :                :      * whether an entry needs an ALTER OWNER command.  We don't want to alter
                              12107                 :                :      * the shell type's owner immediately on creation; that should happen only
                              12108                 :                :      * after it's filled in, otherwise the backend complains.
                              12109                 :                :      */
                              12110                 :                : 
 3470 alvherre@alvh.no-ip.    12111         [ +  + ]:             71 :     if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    12112                 :              8 :         binary_upgrade_set_type_oids_by_type_oid(fout, q,
 2388 tgl@sss.pgh.pa.us       12113                 :              8 :                                                  stinfo->baseType->dobj.catId.oid,
                              12114                 :                :                                                  false, false);
                              12115                 :                : 
 6618                         12116                 :             71 :     appendPQExpBuffer(q, "CREATE TYPE %s;\n",
 2239                         12117                 :             71 :                       fmtQualifiedDumpable(stinfo));
                              12118                 :                : 
 2930 sfrost@snowman.net      12119         [ +  - ]:             71 :     if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12120                 :             71 :         ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    12121                 :             71 :                      ARCHIVE_OPTS(.tag = stinfo->dobj.name,
                              12122                 :                :                                   .namespace = stinfo->dobj.namespace->dobj.name,
                              12123                 :                :                                   .owner = stinfo->baseType->rolname,
                              12124                 :                :                                   .description = "SHELL TYPE",
                              12125                 :                :                                   .section = SECTION_PRE_DATA,
                              12126                 :                :                                   .createStmt = q->data));
                              12127                 :                : 
 6618 tgl@sss.pgh.pa.us       12128                 :             71 :     destroyPQExpBuffer(q);
                              12129                 :                : }
                              12130                 :                : 
                              12131                 :                : /*
                              12132                 :                :  * dumpProcLang
                              12133                 :                :  *        writes out to fout the queries to recreate a user-defined
                              12134                 :                :  *        procedural language
                              12135                 :                :  */
                              12136                 :                : static void
 1159 peter@eisentraut.org    12137                 :             84 : dumpProcLang(Archive *fout, const ProcLangInfo *plang)
                              12138                 :                : {
 3014 tgl@sss.pgh.pa.us       12139                 :             84 :     DumpOptions *dopt = fout->dopt;
                              12140                 :                :     PQExpBuffer defqry;
                              12141                 :                :     PQExpBuffer delqry;
                              12142                 :                :     bool        useParams;
                              12143                 :                :     char       *qlanname;
                              12144                 :                :     FuncInfo   *funcInfo;
 5318                         12145                 :             84 :     FuncInfo   *inlineInfo = NULL;
 7435                         12146                 :             84 :     FuncInfo   *validatorInfo = NULL;
                              12147                 :                : 
                              12148                 :                :     /* Do nothing in data-only dump */
  860                         12149         [ +  + ]:             84 :     if (dopt->dataOnly)
 7435                         12150                 :              7 :         return;
                              12151                 :                : 
                              12152                 :                :     /*
                              12153                 :                :      * Try to find the support function(s).  It is not an error if we don't
                              12154                 :                :      * find them --- if the functions are in the pg_catalog schema, as is
                              12155                 :                :      * standard in 8.1 and up, then we won't have loaded them. (In this case
                              12156                 :                :      * we will emit a parameterless CREATE LANGUAGE command, which will
                              12157                 :                :      * require PL template knowledge in the backend to reload.)
                              12158                 :                :      */
                              12159                 :                : 
                              12160                 :             77 :     funcInfo = findFuncByOid(plang->lanplcallfoid);
 6618                         12161   [ +  +  +  + ]:             77 :     if (funcInfo != NULL && !funcInfo->dobj.dump)
 6796                         12162                 :              2 :         funcInfo = NULL;        /* treat not-dumped same as not-found */
                              12163                 :                : 
 5318                         12164         [ +  + ]:             77 :     if (OidIsValid(plang->laninline))
                              12165                 :                :     {
                              12166                 :             42 :         inlineInfo = findFuncByOid(plang->laninline);
                              12167   [ +  +  +  - ]:             42 :         if (inlineInfo != NULL && !inlineInfo->dobj.dump)
                              12168                 :              1 :             inlineInfo = NULL;
                              12169                 :                :     }
                              12170                 :                : 
 7435                         12171         [ +  + ]:             77 :     if (OidIsValid(plang->lanvalidator))
                              12172                 :                :     {
                              12173                 :             42 :         validatorInfo = findFuncByOid(plang->lanvalidator);
 6618                         12174   [ +  +  +  - ]:             42 :         if (validatorInfo != NULL && !validatorInfo->dobj.dump)
 6796                         12175                 :              1 :             validatorInfo = NULL;
                              12176                 :                :     }
                              12177                 :                : 
                              12178                 :                :     /*
                              12179                 :                :      * If the functions are dumpable then emit a complete CREATE LANGUAGE with
                              12180                 :                :      * parameters.  Otherwise, we'll write a parameterless command, which will
                              12181                 :                :      * be interpreted as CREATE EXTENSION.
                              12182                 :                :      */
                              12183         [ +  - ]:             34 :     useParams = (funcInfo != NULL &&
 5318                         12184   [ +  +  +  -  :            145 :                  (inlineInfo != NULL || !OidIsValid(plang->laninline)) &&
                                              +  - ]
 6796                         12185         [ +  - ]:             34 :                  (validatorInfo != NULL || !OidIsValid(plang->lanvalidator)));
                              12186                 :                : 
 7435                         12187                 :             77 :     defqry = createPQExpBuffer();
                              12188                 :             77 :     delqry = createPQExpBuffer();
                              12189                 :                : 
 4524 bruce@momjian.us        12190                 :             77 :     qlanname = pg_strdup(fmtId(plang->dobj.name));
                              12191                 :                : 
 7435 tgl@sss.pgh.pa.us       12192                 :             77 :     appendPQExpBuffer(delqry, "DROP PROCEDURAL LANGUAGE %s;\n",
                              12193                 :                :                       qlanname);
                              12194                 :                : 
 6796                         12195         [ +  + ]:             77 :     if (useParams)
                              12196                 :                :     {
 5163 tgl@sss.pgh.pa.us       12197                 :UBC           0 :         appendPQExpBuffer(defqry, "CREATE %sPROCEDURAL LANGUAGE %s",
 5163 tgl@sss.pgh.pa.us       12198         [ -  + ]:CBC          34 :                           plang->lanpltrusted ? "TRUSTED " : "",
                              12199                 :                :                           qlanname);
 6796                         12200                 :             34 :         appendPQExpBuffer(defqry, " HANDLER %s",
 2239                         12201                 :             34 :                           fmtQualifiedDumpable(funcInfo));
 5318                         12202         [ -  + ]:             34 :         if (OidIsValid(plang->laninline))
 2239 tgl@sss.pgh.pa.us       12203                 :UBC           0 :             appendPQExpBuffer(defqry, " INLINE %s",
                              12204                 :              0 :                               fmtQualifiedDumpable(inlineInfo));
 6796 tgl@sss.pgh.pa.us       12205         [ -  + ]:CBC          34 :         if (OidIsValid(plang->lanvalidator))
 2239 tgl@sss.pgh.pa.us       12206                 :UBC           0 :             appendPQExpBuffer(defqry, " VALIDATOR %s",
                              12207                 :              0 :                               fmtQualifiedDumpable(validatorInfo));
                              12208                 :                :     }
                              12209                 :                :     else
                              12210                 :                :     {
                              12211                 :                :         /*
                              12212                 :                :          * If not dumping parameters, then use CREATE OR REPLACE so that the
                              12213                 :                :          * command will not fail if the language is preinstalled in the target
                              12214                 :                :          * database.
                              12215                 :                :          *
                              12216                 :                :          * Modern servers will interpret this as CREATE EXTENSION IF NOT
                              12217                 :                :          * EXISTS; perhaps we should emit that instead?  But it might just add
                              12218                 :                :          * confusion.
                              12219                 :                :          */
 5163 tgl@sss.pgh.pa.us       12220                 :CBC          43 :         appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
                              12221                 :                :                           qlanname);
                              12222                 :                :     }
 3800 heikki.linnakangas@i    12223                 :             77 :     appendPQExpBufferStr(defqry, ";\n");
                              12224                 :                : 
 3470 alvherre@alvh.no-ip.    12225         [ +  + ]:             77 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       12226                 :              2 :         binary_upgrade_extension_member(defqry, &plang->dobj,
                              12227                 :                :                                         "LANGUAGE", qlanname, NULL);
                              12228                 :                : 
 2930 sfrost@snowman.net      12229         [ +  + ]:             77 :     if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12230                 :             35 :         ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    12231                 :             35 :                      ARCHIVE_OPTS(.tag = plang->dobj.name,
                              12232                 :                :                                   .owner = plang->lanowner,
                              12233                 :                :                                   .description = "PROCEDURAL LANGUAGE",
                              12234                 :                :                                   .section = SECTION_PRE_DATA,
                              12235                 :                :                                   .createStmt = defqry->data,
                              12236                 :                :                                   .dropStmt = delqry->data,
                              12237                 :                :                                   ));
                              12238                 :                : 
                              12239                 :                :     /* Dump Proc Lang Comments and Security Labels */
 2930 sfrost@snowman.net      12240         [ -  + ]:             77 :     if (plang->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       12241                 :UBC           0 :         dumpComment(fout, "LANGUAGE", qlanname,
                              12242                 :              0 :                     NULL, plang->lanowner,
 2930 sfrost@snowman.net      12243                 :              0 :                     plang->dobj.catId, 0, plang->dobj.dumpId);
                              12244                 :                : 
 2930 sfrost@snowman.net      12245         [ -  + ]:CBC          77 :     if (plang->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       12246                 :UBC           0 :         dumpSecLabel(fout, "LANGUAGE", qlanname,
                              12247                 :              0 :                      NULL, plang->lanowner,
 2930 sfrost@snowman.net      12248                 :              0 :                      plang->dobj.catId, 0, plang->dobj.dumpId);
                              12249                 :                : 
 2930 sfrost@snowman.net      12250   [ +  +  +  - ]:CBC          77 :     if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       12251                 :             42 :         dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
                              12252                 :                :                 qlanname, NULL, NULL,
   13 tgl@sss.pgh.pa.us       12253                 :GNC          42 :                 NULL, plang->lanowner, &plang->dacl);
                              12254                 :                : 
 7435 tgl@sss.pgh.pa.us       12255                 :CBC          77 :     free(qlanname);
                              12256                 :                : 
                              12257                 :             77 :     destroyPQExpBuffer(defqry);
                              12258                 :             77 :     destroyPQExpBuffer(delqry);
                              12259                 :                : }
                              12260                 :                : 
                              12261                 :                : /*
                              12262                 :                :  * format_function_arguments: generate function name and argument list
                              12263                 :                :  *
                              12264                 :                :  * This is used when we can rely on pg_get_function_arguments to format
                              12265                 :                :  * the argument list.  Note, however, that pg_get_function_arguments
                              12266                 :                :  * does not special-case zero-argument aggregates.
                              12267                 :                :  */
                              12268                 :                : static char *
 1159 peter@eisentraut.org    12269                 :           4092 : format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg)
                              12270                 :                : {
                              12271                 :                :     PQExpBufferData fn;
                              12272                 :                : 
 5749 tgl@sss.pgh.pa.us       12273                 :           4092 :     initPQExpBuffer(&fn);
 3800 heikki.linnakangas@i    12274                 :           4092 :     appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
 3876 tgl@sss.pgh.pa.us       12275   [ +  +  +  + ]:           4092 :     if (is_agg && finfo->nargs == 0)
 3800 heikki.linnakangas@i    12276                 :             80 :         appendPQExpBufferStr(&fn, "(*)");
                              12277                 :                :     else
 3876 tgl@sss.pgh.pa.us       12278                 :           4012 :         appendPQExpBuffer(&fn, "(%s)", funcargs);
 5749                         12279                 :           4092 :     return fn.data;
                              12280                 :                : }
                              12281                 :                : 
                              12282                 :                : /*
                              12283                 :                :  * format_function_signature: generate function name and argument list
                              12284                 :                :  *
                              12285                 :                :  * Only a minimal list of input argument types is generated; this is
                              12286                 :                :  * sufficient to reference the function, but not to define it.
                              12287                 :                :  *
                              12288                 :                :  * If honor_quotes is false then the function name is never quoted.
                              12289                 :                :  * This is appropriate for use in TOC tags, but not in SQL commands.
                              12290                 :                :  */
                              12291                 :                : static char *
 1159 peter@eisentraut.org    12292                 :           2166 : format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes)
                              12293                 :                : {
                              12294                 :                :     PQExpBufferData fn;
                              12295                 :                :     int         j;
                              12296                 :                : 
 6953 tgl@sss.pgh.pa.us       12297                 :           2166 :     initPQExpBuffer(&fn);
                              12298         [ +  + ]:           2166 :     if (honor_quotes)
                              12299                 :            409 :         appendPQExpBuffer(&fn, "%s(", fmtId(finfo->dobj.name));
                              12300                 :                :     else
                              12301                 :           1757 :         appendPQExpBuffer(&fn, "%s(", finfo->dobj.name);
                              12302         [ +  + ]:           3970 :     for (j = 0; j < finfo->nargs; j++)
                              12303                 :                :     {
 3800 heikki.linnakangas@i    12304         [ +  + ]:           1804 :         if (j > 0)
                              12305                 :            417 :             appendPQExpBufferStr(&fn, ", ");
                              12306                 :                : 
  949 tgl@sss.pgh.pa.us       12307                 :           1804 :         appendPQExpBufferStr(&fn,
                              12308                 :           1804 :                              getFormattedTypeName(fout, finfo->argtypes[j],
                              12309                 :                :                                                   zeroIsError));
                              12310                 :                :     }
 3800 heikki.linnakangas@i    12311                 :           2166 :     appendPQExpBufferChar(&fn, ')');
 6953 tgl@sss.pgh.pa.us       12312                 :           2166 :     return fn.data;
                              12313                 :                : }
                              12314                 :                : 
                              12315                 :                : 
                              12316                 :                : /*
                              12317                 :                :  * dumpFunc:
                              12318                 :                :  *    dump out one function
                              12319                 :                :  */
                              12320                 :                : static void
 1159 peter@eisentraut.org    12321                 :           1789 : dumpFunc(Archive *fout, const FuncInfo *finfo)
                              12322                 :                : {
 3014 tgl@sss.pgh.pa.us       12323                 :           1789 :     DumpOptions *dopt = fout->dopt;
                              12324                 :                :     PQExpBuffer query;
                              12325                 :                :     PQExpBuffer q;
                              12326                 :                :     PQExpBuffer delqry;
                              12327                 :                :     PQExpBuffer asPart;
                              12328                 :                :     PGresult   *res;
                              12329                 :                :     char       *funcsig;        /* identity signature */
 2489                         12330                 :           1789 :     char       *funcfullsig = NULL; /* full signature */
                              12331                 :                :     char       *funcsig_tag;
                              12332                 :                :     char       *qual_funcsig;
                              12333                 :                :     char       *proretset;
                              12334                 :                :     char       *prosrc;
                              12335                 :                :     char       *probin;
                              12336                 :                :     char       *prosqlbody;
                              12337                 :                :     char       *funcargs;
                              12338                 :                :     char       *funciargs;
                              12339                 :                :     char       *funcresult;
                              12340                 :                :     char       *protrftypes;
                              12341                 :                :     char       *prokind;
                              12342                 :                :     char       *provolatile;
                              12343                 :                :     char       *proisstrict;
                              12344                 :                :     char       *prosecdef;
                              12345                 :                :     char       *proleakproof;
                              12346                 :                :     char       *proconfig;
                              12347                 :                :     char       *procost;
                              12348                 :                :     char       *prorows;
                              12349                 :                :     char       *prosupport;
                              12350                 :                :     char       *proparallel;
                              12351                 :                :     char       *lanname;
 6068                         12352                 :           1789 :     char      **configitems = NULL;
                              12353                 :           1789 :     int         nconfigitems = 0;
                              12354                 :                :     const char *keyword;
                              12355                 :                : 
                              12356                 :                :     /* Do nothing in data-only dump */
  860                         12357         [ +  + ]:           1789 :     if (dopt->dataOnly)
 6817                         12358                 :             32 :         return;
                              12359                 :                : 
 7435                         12360                 :           1757 :     query = createPQExpBuffer();
                              12361                 :           1757 :     q = createPQExpBuffer();
                              12362                 :           1757 :     delqry = createPQExpBuffer();
                              12363                 :           1757 :     asPart = createPQExpBuffer();
                              12364                 :                : 
  860                         12365         [ +  + ]:           1757 :     if (!fout->is_prepared[PREPQUERY_DUMPFUNC])
                              12366                 :                :     {
                              12367                 :                :         /* Set up query for function-specific details */
 1277 drowley@postgresql.o    12368                 :             63 :         appendPQExpBufferStr(query,
                              12369                 :                :                              "PREPARE dumpFunc(pg_catalog.oid) AS\n");
                              12370                 :                : 
                              12371                 :             63 :         appendPQExpBufferStr(query,
                              12372                 :                :                              "SELECT\n"
                              12373                 :                :                              "proretset,\n"
                              12374                 :                :                              "prosrc,\n"
                              12375                 :                :                              "probin,\n"
                              12376                 :                :                              "provolatile,\n"
                              12377                 :                :                              "proisstrict,\n"
                              12378                 :                :                              "prosecdef,\n"
                              12379                 :                :                              "lanname,\n"
                              12380                 :                :                              "proconfig,\n"
                              12381                 :                :                              "procost,\n"
                              12382                 :                :                              "prorows,\n"
                              12383                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              12384                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n"
                              12385                 :                :                              "pg_catalog.pg_get_function_result(p.oid) AS funcresult,\n"
                              12386                 :                :                              "proleakproof,\n");
                              12387                 :                : 
  860 tgl@sss.pgh.pa.us       12388         [ +  - ]:             63 :         if (fout->remoteVersion >= 90500)
                              12389                 :             63 :             appendPQExpBufferStr(query,
                              12390                 :                :                                  "array_to_string(protrftypes, ' ') AS protrftypes,\n");
                              12391                 :                :         else
  847 tgl@sss.pgh.pa.us       12392                 :UBC           0 :             appendPQExpBufferStr(query,
                              12393                 :                :                                  "NULL AS protrftypes,\n");
                              12394                 :                : 
  860 tgl@sss.pgh.pa.us       12395         [ +  - ]:CBC          63 :         if (fout->remoteVersion >= 90600)
                              12396                 :             63 :             appendPQExpBufferStr(query,
                              12397                 :                :                                  "proparallel,\n");
                              12398                 :                :         else
  860 tgl@sss.pgh.pa.us       12399                 :UBC           0 :             appendPQExpBufferStr(query,
                              12400                 :                :                                  "'u' AS proparallel,\n");
                              12401                 :                : 
  860 tgl@sss.pgh.pa.us       12402         [ +  - ]:CBC          63 :         if (fout->remoteVersion >= 110000)
                              12403                 :             63 :             appendPQExpBufferStr(query,
                              12404                 :                :                                  "prokind,\n");
                              12405                 :                :         else
  860 tgl@sss.pgh.pa.us       12406                 :UBC           0 :             appendPQExpBufferStr(query,
                              12407                 :                :                                  "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind,\n");
                              12408                 :                : 
  860 tgl@sss.pgh.pa.us       12409         [ +  - ]:CBC          63 :         if (fout->remoteVersion >= 120000)
                              12410                 :             63 :             appendPQExpBufferStr(query,
                              12411                 :                :                                  "prosupport,\n");
                              12412                 :                :         else
  860 tgl@sss.pgh.pa.us       12413                 :UBC           0 :             appendPQExpBufferStr(query,
                              12414                 :                :                                  "'-' AS prosupport,\n");
                              12415                 :                : 
  860 tgl@sss.pgh.pa.us       12416         [ +  - ]:CBC          63 :         if (fout->remoteVersion >= 140000)
                              12417                 :             63 :             appendPQExpBufferStr(query,
                              12418                 :                :                                  "pg_get_function_sqlbody(p.oid) AS prosqlbody\n");
                              12419                 :                :         else
  860 tgl@sss.pgh.pa.us       12420                 :UBC           0 :             appendPQExpBufferStr(query,
                              12421                 :                :                                  "NULL AS prosqlbody\n");
                              12422                 :                : 
 1103 peter@eisentraut.org    12423                 :CBC          63 :         appendPQExpBufferStr(query,
                              12424                 :                :                              "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n"
                              12425                 :                :                              "WHERE p.oid = $1 "
                              12426                 :                :                              "AND l.oid = p.prolang");
                              12427                 :                : 
  860 tgl@sss.pgh.pa.us       12428                 :             63 :         ExecuteSqlStatement(fout, query->data);
                              12429                 :                : 
                              12430                 :             63 :         fout->is_prepared[PREPQUERY_DUMPFUNC] = true;
                              12431                 :                :     }
                              12432                 :                : 
                              12433                 :           1757 :     printfPQExpBuffer(query,
                              12434                 :                :                       "EXECUTE dumpFunc('%u')",
 1369 peter@eisentraut.org    12435                 :           1757 :                       finfo->dobj.catId.oid);
                              12436                 :                : 
 4441 rhaas@postgresql.org    12437                 :           1757 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              12438                 :                : 
 8010 tgl@sss.pgh.pa.us       12439                 :           1757 :     proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
 1103 peter@eisentraut.org    12440         [ +  + ]:           1757 :     if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody")))
                              12441                 :                :     {
                              12442                 :           1705 :         prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
                              12443                 :           1705 :         probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
                              12444                 :           1705 :         prosqlbody = NULL;
                              12445                 :                :     }
                              12446                 :                :     else
                              12447                 :                :     {
                              12448                 :             52 :         prosrc = NULL;
                              12449                 :             52 :         probin = NULL;
                              12450                 :             52 :         prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody"));
                              12451                 :                :     }
  852 tgl@sss.pgh.pa.us       12452                 :           1757 :     funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              12453                 :           1757 :     funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              12454                 :           1757 :     funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult"));
  847                         12455                 :           1757 :     protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes"));
 2235 peter_e@gmx.net         12456                 :           1757 :     prokind = PQgetvalue(res, 0, PQfnumber(res, "prokind"));
 8010 tgl@sss.pgh.pa.us       12457                 :           1757 :     provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
                              12458                 :           1757 :     proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
 8002 peter_e@gmx.net         12459                 :           1757 :     prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
 4444 rhaas@postgresql.org    12460                 :           1757 :     proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
 6068 tgl@sss.pgh.pa.us       12461                 :           1757 :     proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
 6292                         12462                 :           1757 :     procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
                              12463                 :           1757 :     prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
 1891                         12464                 :           1757 :     prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport"));
 1369 peter@eisentraut.org    12465                 :           1757 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
 8010 tgl@sss.pgh.pa.us       12466                 :           1757 :     lanname = PQgetvalue(res, 0, PQfnumber(res, "lanname"));
                              12467                 :                : 
                              12468                 :                :     /*
                              12469                 :                :      * See backend/commands/functioncmds.c for details of how the 'AS' clause
                              12470                 :                :      * is used.
                              12471                 :                :      */
 1103 peter@eisentraut.org    12472         [ +  + ]:           1757 :     if (prosqlbody)
                              12473                 :                :     {
                              12474                 :             52 :         appendPQExpBufferStr(asPart, prosqlbody);
                              12475                 :                :     }
  850 tgl@sss.pgh.pa.us       12476         [ +  + ]:           1705 :     else if (probin[0] != '\0')
                              12477                 :                :     {
 3800 heikki.linnakangas@i    12478                 :            146 :         appendPQExpBufferStr(asPart, "AS ");
 6531 tgl@sss.pgh.pa.us       12479                 :            146 :         appendStringLiteralAH(asPart, probin, fout);
  850                         12480         [ +  - ]:            146 :         if (prosrc[0] != '\0')
                              12481                 :                :         {
 3800 heikki.linnakangas@i    12482                 :            146 :             appendPQExpBufferStr(asPart, ", ");
                              12483                 :                : 
                              12484                 :                :             /*
                              12485                 :                :              * where we have bin, use dollar quoting if allowed and src
                              12486                 :                :              * contains quote or backslash; else use regular quoting.
                              12487                 :                :              */
 3470 alvherre@alvh.no-ip.    12488         [ +  - ]:            146 :             if (dopt->disable_dollar_quoting ||
 2489 tgl@sss.pgh.pa.us       12489   [ +  -  +  - ]:            146 :                 (strchr(prosrc, '\'') == NULL && strchr(prosrc, '\\') == NULL))
 6531                         12490                 :            146 :                 appendStringLiteralAH(asPart, prosrc, fout);
                              12491                 :                :             else
 6531 tgl@sss.pgh.pa.us       12492                 :UBC           0 :                 appendStringLiteralDQ(asPart, prosrc, NULL);
                              12493                 :                :         }
                              12494                 :                :     }
                              12495                 :                :     else
                              12496                 :                :     {
  850 tgl@sss.pgh.pa.us       12497                 :CBC        1559 :         appendPQExpBufferStr(asPart, "AS ");
                              12498                 :                :         /* with no bin, dollar quote src unconditionally if allowed */
                              12499         [ -  + ]:           1559 :         if (dopt->disable_dollar_quoting)
  850 tgl@sss.pgh.pa.us       12500                 :UBC           0 :             appendStringLiteralAH(asPart, prosrc, fout);
                              12501                 :                :         else
  850 tgl@sss.pgh.pa.us       12502                 :CBC        1559 :             appendStringLiteralDQ(asPart, prosrc, NULL);
                              12503                 :                :     }
                              12504                 :                : 
  847                         12505         [ +  + ]:           1757 :     if (*proconfig)
                              12506                 :                :     {
 6068                         12507         [ -  + ]:             15 :         if (!parsePGArray(proconfig, &configitems, &nconfigitems))
  737 tgl@sss.pgh.pa.us       12508                 :UBC           0 :             pg_fatal("could not parse %s array", "proconfig");
                              12509                 :                :     }
                              12510                 :                :     else
                              12511                 :                :     {
 1242 michael@paquier.xyz     12512                 :CBC        1742 :         configitems = NULL;
                              12513                 :           1742 :         nconfigitems = 0;
                              12514                 :                :     }
                              12515                 :                : 
  852 tgl@sss.pgh.pa.us       12516                 :           1757 :     funcfullsig = format_function_arguments(finfo, funcargs, false);
                              12517                 :           1757 :     funcsig = format_function_arguments(finfo, funciargs, false);
                              12518                 :                : 
 4451 rhaas@postgresql.org    12519                 :           1757 :     funcsig_tag = format_function_signature(fout, finfo, false);
                              12520                 :                : 
  903 tgl@sss.pgh.pa.us       12521                 :           1757 :     qual_funcsig = psprintf("%s.%s",
                              12522                 :           1757 :                             fmtId(finfo->dobj.namespace->dobj.name),
                              12523                 :                :                             funcsig);
                              12524                 :                : 
 2235 peter_e@gmx.net         12525         [ +  + ]:           1757 :     if (prokind[0] == PROKIND_PROCEDURE)
                              12526                 :             81 :         keyword = "PROCEDURE";
                              12527                 :                :     else
                              12528                 :           1676 :         keyword = "FUNCTION"; /* works for window functions too */
                              12529                 :                : 
  903 tgl@sss.pgh.pa.us       12530                 :           1757 :     appendPQExpBuffer(delqry, "DROP %s %s;\n",
                              12531                 :                :                       keyword, qual_funcsig);
                              12532                 :                : 
 2239                         12533         [ +  - ]:           3514 :     appendPQExpBuffer(q, "CREATE %s %s.%s",
                              12534                 :                :                       keyword,
                              12535                 :           1757 :                       fmtId(finfo->dobj.namespace->dobj.name),
                              12536                 :                :                       funcfullsig ? funcfullsig :
                              12537                 :                :                       funcsig);
                              12538                 :                : 
 2235 peter_e@gmx.net         12539         [ +  + ]:           1757 :     if (prokind[0] == PROKIND_PROCEDURE)
                              12540                 :                :          /* no result type to output */ ;
 2327                         12541         [ +  - ]:           1676 :     else if (funcresult)
                              12542                 :           1676 :         appendPQExpBuffer(q, " RETURNS %s", funcresult);
                              12543                 :                :     else
 2327 peter_e@gmx.net         12544                 :UBC           0 :         appendPQExpBuffer(q, " RETURNS %s%s",
 5749 tgl@sss.pgh.pa.us       12545         [ #  # ]:              0 :                           (proretset[0] == 't') ? "SETOF " : "",
  949                         12546                 :              0 :                           getFormattedTypeName(fout, finfo->prorettype,
                              12547                 :                :                                                zeroIsError));
                              12548                 :                : 
 5766 heikki.linnakangas@i    12549                 :CBC        1757 :     appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));
                              12550                 :                : 
  847 tgl@sss.pgh.pa.us       12551         [ -  + ]:           1757 :     if (*protrftypes)
                              12552                 :                :     {
 3249 bruce@momjian.us        12553                 :UBC           0 :         Oid        *typeids = palloc(FUNC_MAX_ARGS * sizeof(Oid));
                              12554                 :                :         int         i;
                              12555                 :                : 
 3276 peter_e@gmx.net         12556                 :              0 :         appendPQExpBufferStr(q, " TRANSFORM ");
                              12557                 :              0 :         parseOidArray(protrftypes, typeids, FUNC_MAX_ARGS);
                              12558         [ #  # ]:              0 :         for (i = 0; typeids[i]; i++)
                              12559                 :                :         {
                              12560         [ #  # ]:              0 :             if (i != 0)
                              12561                 :              0 :                 appendPQExpBufferStr(q, ", ");
                              12562                 :              0 :             appendPQExpBuffer(q, "FOR TYPE %s",
 2489 tgl@sss.pgh.pa.us       12563                 :              0 :                               getFormattedTypeName(fout, typeids[i], zeroAsNone));
                              12564                 :                :         }
                              12565                 :                :     }
                              12566                 :                : 
 2235 peter_e@gmx.net         12567         [ +  + ]:CBC        1757 :     if (prokind[0] == PROKIND_WINDOW)
 3800 heikki.linnakangas@i    12568                 :              5 :         appendPQExpBufferStr(q, " WINDOW");
                              12569                 :                : 
 8003 peter_e@gmx.net         12570         [ +  + ]:           1757 :     if (provolatile[0] != PROVOLATILE_VOLATILE)
                              12571                 :                :     {
 8010 tgl@sss.pgh.pa.us       12572         [ +  + ]:            350 :         if (provolatile[0] == PROVOLATILE_IMMUTABLE)
 3800 heikki.linnakangas@i    12573                 :            334 :             appendPQExpBufferStr(q, " IMMUTABLE");
 8010 tgl@sss.pgh.pa.us       12574         [ +  - ]:             16 :         else if (provolatile[0] == PROVOLATILE_STABLE)
 3800 heikki.linnakangas@i    12575                 :             16 :             appendPQExpBufferStr(q, " STABLE");
 8010 tgl@sss.pgh.pa.us       12576         [ #  # ]:UBC           0 :         else if (provolatile[0] != PROVOLATILE_VOLATILE)
  737                         12577                 :              0 :             pg_fatal("unrecognized provolatile value for function \"%s\"",
                              12578                 :                :                      finfo->dobj.name);
                              12579                 :                :     }
                              12580                 :                : 
 8003 peter_e@gmx.net         12581         [ +  + ]:CBC        1757 :     if (proisstrict[0] == 't')
 3800 heikki.linnakangas@i    12582                 :            356 :         appendPQExpBufferStr(q, " STRICT");
                              12583                 :                : 
 8002 peter_e@gmx.net         12584         [ -  + ]:           1757 :     if (prosecdef[0] == 't')
 3800 heikki.linnakangas@i    12585                 :UBC           0 :         appendPQExpBufferStr(q, " SECURITY DEFINER");
                              12586                 :                : 
 4444 rhaas@postgresql.org    12587         [ +  + ]:CBC        1757 :     if (proleakproof[0] == 't')
 3800 heikki.linnakangas@i    12588                 :             10 :         appendPQExpBufferStr(q, " LEAKPROOF");
                              12589                 :                : 
                              12590                 :                :     /*
                              12591                 :                :      * COST and ROWS are emitted only if present and not default, so as not to
                              12592                 :                :      * break backwards-compatibility of the dump without need.  Keep this code
                              12593                 :                :      * in sync with the defaults in functioncmds.c.
                              12594                 :                :      */
 6292 tgl@sss.pgh.pa.us       12595         [ +  - ]:           1757 :     if (strcmp(procost, "0") != 0)
                              12596                 :                :     {
                              12597   [ +  +  +  + ]:           1757 :         if (strcmp(lanname, "internal") == 0 || strcmp(lanname, "c") == 0)
                              12598                 :                :         {
                              12599                 :                :             /* default cost is 1 */
                              12600         [ -  + ]:            387 :             if (strcmp(procost, "1") != 0)
 6292 tgl@sss.pgh.pa.us       12601                 :UBC           0 :                 appendPQExpBuffer(q, " COST %s", procost);
                              12602                 :                :         }
                              12603                 :                :         else
                              12604                 :                :         {
                              12605                 :                :             /* default cost is 100 */
 6292 tgl@sss.pgh.pa.us       12606         [ +  + ]:CBC        1370 :             if (strcmp(procost, "100") != 0)
                              12607                 :              6 :                 appendPQExpBuffer(q, " COST %s", procost);
                              12608                 :                :         }
                              12609                 :                :     }
                              12610         [ +  + ]:           1757 :     if (proretset[0] == 't' &&
                              12611   [ +  -  -  + ]:            191 :         strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0)
 6292 tgl@sss.pgh.pa.us       12612                 :UBC           0 :         appendPQExpBuffer(q, " ROWS %s", prorows);
                              12613                 :                : 
 1891 tgl@sss.pgh.pa.us       12614         [ +  + ]:CBC        1757 :     if (strcmp(prosupport, "-") != 0)
                              12615                 :                :     {
                              12616                 :                :         /* We rely on regprocout to provide quoting and qualification */
                              12617                 :             46 :         appendPQExpBuffer(q, " SUPPORT %s", prosupport);
                              12618                 :                :     }
                              12619                 :                : 
 1369 peter@eisentraut.org    12620         [ +  + ]:           1757 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              12621                 :                :     {
 3133 rhaas@postgresql.org    12622         [ +  + ]:            120 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              12623                 :            115 :             appendPQExpBufferStr(q, " PARALLEL SAFE");
                              12624         [ +  - ]:              5 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              12625                 :              5 :             appendPQExpBufferStr(q, " PARALLEL RESTRICTED");
 3133 rhaas@postgresql.org    12626         [ #  # ]:UBC           0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
  737 tgl@sss.pgh.pa.us       12627                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              12628                 :                :                      finfo->dobj.name);
                              12629                 :                :     }
                              12630                 :                : 
  599 drowley@postgresql.o    12631         [ +  + ]:CBC        1792 :     for (int i = 0; i < nconfigitems; i++)
                              12632                 :                :     {
                              12633                 :                :         /* we feel free to scribble on configitems[] here */
 6068 tgl@sss.pgh.pa.us       12634                 :             35 :         char       *configitem = configitems[i];
                              12635                 :                :         char       *pos;
                              12636                 :                : 
                              12637                 :             35 :         pos = strchr(configitem, '=');
                              12638         [ -  + ]:             35 :         if (pos == NULL)
 6068 tgl@sss.pgh.pa.us       12639                 :UBC           0 :             continue;
 6068 tgl@sss.pgh.pa.us       12640                 :CBC          35 :         *pos++ = '\0';
                              12641                 :             35 :         appendPQExpBuffer(q, "\n    SET %s TO ", fmtId(configitem));
                              12642                 :                : 
                              12643                 :                :         /*
                              12644                 :                :          * Variables that are marked GUC_LIST_QUOTE were already fully quoted
                              12645                 :                :          * by flatten_set_variable_args() before they were put into the
                              12646                 :                :          * proconfig array.  However, because the quoting rules used there
                              12647                 :                :          * aren't exactly like SQL's, we have to break the list value apart
                              12648                 :                :          * and then quote the elements as string literals.  (The elements may
                              12649                 :                :          * be double-quoted as-is, but we can't just feed them to the SQL
                              12650                 :                :          * parser; it would do the wrong thing with elements that are
                              12651                 :                :          * zero-length or longer than NAMEDATALEN.)
                              12652                 :                :          *
                              12653                 :                :          * Variables that are not so marked should just be emitted as simple
                              12654                 :                :          * string literals.  If the variable is not known to
                              12655                 :                :          * variable_is_guc_list_quote(), we'll do that; this makes it unsafe
                              12656                 :                :          * to use GUC_LIST_QUOTE for extension variables.
                              12657                 :                :          */
 2216                         12658         [ +  + ]:             35 :         if (variable_is_guc_list_quote(configitem))
                              12659                 :                :         {
                              12660                 :                :             char      **namelist;
                              12661                 :                :             char      **nameptr;
                              12662                 :                : 
                              12663                 :                :             /* Parse string into list of identifiers */
                              12664                 :                :             /* this shouldn't fail really */
 2084                         12665         [ +  - ]:             10 :             if (SplitGUCList(pos, ',', &namelist))
                              12666                 :                :             {
                              12667         [ +  + ]:             35 :                 for (nameptr = namelist; *nameptr; nameptr++)
                              12668                 :                :                 {
                              12669         [ +  + ]:             25 :                     if (nameptr != namelist)
                              12670                 :             15 :                         appendPQExpBufferStr(q, ", ");
                              12671                 :             25 :                     appendStringLiteralAH(q, *nameptr, fout);
                              12672                 :                :                 }
                              12673                 :                :             }
                              12674                 :             10 :             pg_free(namelist);
                              12675                 :                :         }
                              12676                 :                :         else
 6068                         12677                 :             25 :             appendStringLiteralAH(q, pos, fout);
                              12678                 :                :     }
                              12679                 :                : 
 5766 heikki.linnakangas@i    12680                 :           1757 :     appendPQExpBuffer(q, "\n    %s;\n", asPart->data);
                              12681                 :                : 
 1495 alvherre@alvh.no-ip.    12682                 :           1757 :     append_depends_on_extension(fout, q, &finfo->dobj,
                              12683                 :                :                                 "pg_catalog.pg_proc", keyword,
                              12684                 :                :                                 qual_funcsig);
                              12685                 :                : 
 3470                         12686         [ +  + ]:           1757 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       12687                 :            282 :         binary_upgrade_extension_member(q, &finfo->dobj,
                              12688                 :                :                                         keyword, funcsig,
                              12689                 :            282 :                                         finfo->dobj.namespace->dobj.name);
                              12690                 :                : 
 2930 sfrost@snowman.net      12691         [ +  + ]:           1757 :     if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12692                 :           1653 :         ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    12693         [ +  + ]:           1653 :                      ARCHIVE_OPTS(.tag = funcsig_tag,
                              12694                 :                :                                   .namespace = finfo->dobj.namespace->dobj.name,
                              12695                 :                :                                   .owner = finfo->rolname,
                              12696                 :                :                                   .description = keyword,
                              12697                 :                :                                   .section = finfo->postponed_def ?
                              12698                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              12699                 :                :                                   .createStmt = q->data,
                              12700                 :                :                                   .dropStmt = delqry->data));
                              12701                 :                : 
                              12702                 :                :     /* Dump Function Comments and Security Labels */
 2930 sfrost@snowman.net      12703         [ +  + ]:           1757 :     if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       12704                 :              5 :         dumpComment(fout, keyword, funcsig,
 2930 sfrost@snowman.net      12705                 :              5 :                     finfo->dobj.namespace->dobj.name, finfo->rolname,
                              12706                 :              5 :                     finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              12707                 :                : 
                              12708         [ -  + ]:           1757 :     if (finfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       12709                 :UBC           0 :         dumpSecLabel(fout, keyword, funcsig,
 2930 sfrost@snowman.net      12710                 :              0 :                      finfo->dobj.namespace->dobj.name, finfo->rolname,
                              12711                 :              0 :                      finfo->dobj.catId, 0, finfo->dobj.dumpId);
                              12712                 :                : 
 2930 sfrost@snowman.net      12713         [ +  + ]:CBC        1757 :     if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       12714                 :            108 :         dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
                              12715                 :                :                 funcsig, NULL,
 2930 sfrost@snowman.net      12716                 :            108 :                 finfo->dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       12717                 :GNC         108 :                 NULL, finfo->rolname, &finfo->dacl);
                              12718                 :                : 
 8010 tgl@sss.pgh.pa.us       12719                 :CBC        1757 :     PQclear(res);
                              12720                 :                : 
                              12721                 :           1757 :     destroyPQExpBuffer(query);
 8290                         12722                 :           1757 :     destroyPQExpBuffer(q);
                              12723                 :           1757 :     destroyPQExpBuffer(delqry);
                              12724                 :           1757 :     destroyPQExpBuffer(asPart);
 8001 peter_e@gmx.net         12725                 :           1757 :     free(funcsig);
  668 peter@eisentraut.org    12726                 :           1757 :     free(funcfullsig);
 7955 bruce@momjian.us        12727                 :           1757 :     free(funcsig_tag);
  903 tgl@sss.pgh.pa.us       12728                 :           1757 :     free(qual_funcsig);
  668 peter@eisentraut.org    12729                 :           1757 :     free(configitems);
                              12730                 :                : }
                              12731                 :                : 
                              12732                 :                : 
                              12733                 :                : /*
                              12734                 :                :  * Dump a user-defined cast
                              12735                 :                :  */
                              12736                 :                : static void
 1159                         12737                 :             68 : dumpCast(Archive *fout, const CastInfo *cast)
                              12738                 :                : {
 3014 tgl@sss.pgh.pa.us       12739                 :             68 :     DumpOptions *dopt = fout->dopt;
                              12740                 :                :     PQExpBuffer defqry;
                              12741                 :                :     PQExpBuffer delqry;
                              12742                 :                :     PQExpBuffer labelq;
                              12743                 :                :     PQExpBuffer castargs;
 7435                         12744                 :             68 :     FuncInfo   *funcInfo = NULL;
                              12745                 :                :     const char *sourceType;
                              12746                 :                :     const char *targetType;
                              12747                 :                : 
                              12748                 :                :     /* Do nothing in data-only dump */
  860                         12749         [ +  + ]:             68 :     if (dopt->dataOnly)
 7435                         12750                 :              3 :         return;
                              12751                 :                : 
                              12752                 :                :     /* Cannot dump if we don't have the cast function's info */
                              12753         [ +  + ]:             65 :     if (OidIsValid(cast->castfunc))
                              12754                 :                :     {
                              12755                 :             40 :         funcInfo = findFuncByOid(cast->castfunc);
                              12756         [ -  + ]:             40 :         if (funcInfo == NULL)
  737 tgl@sss.pgh.pa.us       12757                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              12758                 :                :                      cast->castfunc);
                              12759                 :                :     }
                              12760                 :                : 
 7435 tgl@sss.pgh.pa.us       12761                 :CBC          65 :     defqry = createPQExpBuffer();
                              12762                 :             65 :     delqry = createPQExpBuffer();
 4813                         12763                 :             65 :     labelq = createPQExpBuffer();
 2239                         12764                 :             65 :     castargs = createPQExpBuffer();
                              12765                 :                : 
 3209 heikki.linnakangas@i    12766                 :             65 :     sourceType = getFormattedTypeName(fout, cast->castsource, zeroAsNone);
                              12767                 :             65 :     targetType = getFormattedTypeName(fout, cast->casttarget, zeroAsNone);
 7435 tgl@sss.pgh.pa.us       12768                 :             65 :     appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
                              12769                 :                :                       sourceType, targetType);
                              12770                 :                : 
                              12771                 :             65 :     appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
                              12772                 :                :                       sourceType, targetType);
                              12773                 :                : 
 5421 bruce@momjian.us        12774   [ +  -  +  - ]:             65 :     switch (cast->castmethod)
                              12775                 :                :     {
 5644 heikki.linnakangas@i    12776                 :             25 :         case COERCION_METHOD_BINARY:
 3800                         12777                 :             25 :             appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
 5644                         12778                 :             25 :             break;
 5644 heikki.linnakangas@i    12779                 :UBC           0 :         case COERCION_METHOD_INOUT:
 3800                         12780                 :              0 :             appendPQExpBufferStr(defqry, "WITH INOUT");
 5644                         12781                 :              0 :             break;
 5644 heikki.linnakangas@i    12782                 :CBC          40 :         case COERCION_METHOD_FUNCTION:
 4412 peter_e@gmx.net         12783         [ +  - ]:             40 :             if (funcInfo)
                              12784                 :                :             {
 4326 bruce@momjian.us        12785                 :             40 :                 char       *fsig = format_function_signature(fout, funcInfo, true);
                              12786                 :                : 
                              12787                 :                :                 /*
                              12788                 :                :                  * Always qualify the function name (format_function_signature
                              12789                 :                :                  * won't qualify it).
                              12790                 :                :                  */
 4412 peter_e@gmx.net         12791                 :             40 :                 appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
 2489 tgl@sss.pgh.pa.us       12792                 :             40 :                                   fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
 4412 peter_e@gmx.net         12793                 :             40 :                 free(fsig);
                              12794                 :                :             }
                              12795                 :                :             else
 1840 peter@eisentraut.org    12796                 :UBC           0 :                 pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field");
 5644 heikki.linnakangas@i    12797                 :CBC          40 :             break;
 5644 heikki.linnakangas@i    12798                 :UBC           0 :         default:
 1840 peter@eisentraut.org    12799                 :              0 :             pg_log_warning("bogus value in pg_cast.castmethod field");
                              12800                 :                :     }
                              12801                 :                : 
 7435 tgl@sss.pgh.pa.us       12802         [ +  + ]:CBC          65 :     if (cast->castcontext == 'a')
 3800 heikki.linnakangas@i    12803                 :             35 :         appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
 7435 tgl@sss.pgh.pa.us       12804         [ +  + ]:             30 :     else if (cast->castcontext == 'i')
 3800 heikki.linnakangas@i    12805                 :             10 :         appendPQExpBufferStr(defqry, " AS IMPLICIT");
                              12806                 :             65 :     appendPQExpBufferStr(defqry, ";\n");
                              12807                 :                : 
 4813 tgl@sss.pgh.pa.us       12808                 :             65 :     appendPQExpBuffer(labelq, "CAST (%s AS %s)",
                              12809                 :                :                       sourceType, targetType);
                              12810                 :                : 
 2239                         12811                 :             65 :     appendPQExpBuffer(castargs, "(%s AS %s)",
                              12812                 :                :                       sourceType, targetType);
                              12813                 :                : 
 3470 alvherre@alvh.no-ip.    12814         [ +  + ]:             65 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       12815                 :              7 :         binary_upgrade_extension_member(defqry, &cast->dobj,
                              12816                 :              7 :                                         "CAST", castargs->data, NULL);
                              12817                 :                : 
 2930 sfrost@snowman.net      12818         [ +  - ]:             65 :     if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12819                 :             65 :         ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    12820                 :             65 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              12821                 :                :                                   .description = "CAST",
                              12822                 :                :                                   .section = SECTION_PRE_DATA,
                              12823                 :                :                                   .createStmt = defqry->data,
                              12824                 :                :                                   .dropStmt = delqry->data));
                              12825                 :                : 
                              12826                 :                :     /* Dump Cast Comments */
 2930 sfrost@snowman.net      12827         [ -  + ]:             65 :     if (cast->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       12828                 :UBC           0 :         dumpComment(fout, "CAST", castargs->data,
                              12829                 :                :                     NULL, "",
 2930 sfrost@snowman.net      12830                 :              0 :                     cast->dobj.catId, 0, cast->dobj.dumpId);
                              12831                 :                : 
 7941 peter_e@gmx.net         12832                 :CBC          65 :     destroyPQExpBuffer(defqry);
                              12833                 :             65 :     destroyPQExpBuffer(delqry);
 4813 tgl@sss.pgh.pa.us       12834                 :             65 :     destroyPQExpBuffer(labelq);
 2239                         12835                 :             65 :     destroyPQExpBuffer(castargs);
                              12836                 :                : }
                              12837                 :                : 
                              12838                 :                : /*
                              12839                 :                :  * Dump a transform
                              12840                 :                :  */
                              12841                 :                : static void
 1159 peter@eisentraut.org    12842                 :             43 : dumpTransform(Archive *fout, const TransformInfo *transform)
                              12843                 :                : {
 3014 tgl@sss.pgh.pa.us       12844                 :             43 :     DumpOptions *dopt = fout->dopt;
                              12845                 :                :     PQExpBuffer defqry;
                              12846                 :                :     PQExpBuffer delqry;
                              12847                 :                :     PQExpBuffer labelq;
                              12848                 :                :     PQExpBuffer transformargs;
 3276 peter_e@gmx.net         12849                 :             43 :     FuncInfo   *fromsqlFuncInfo = NULL;
                              12850                 :             43 :     FuncInfo   *tosqlFuncInfo = NULL;
                              12851                 :                :     char       *lanname;
                              12852                 :                :     const char *transformType;
                              12853                 :                : 
                              12854                 :                :     /* Do nothing in data-only dump */
  860 tgl@sss.pgh.pa.us       12855         [ +  + ]:             43 :     if (dopt->dataOnly)
 3276 peter_e@gmx.net         12856                 :              3 :         return;
                              12857                 :                : 
                              12858                 :                :     /* Cannot dump if we don't have the transform functions' info */
                              12859         [ +  - ]:             40 :     if (OidIsValid(transform->trffromsql))
                              12860                 :                :     {
                              12861                 :             40 :         fromsqlFuncInfo = findFuncByOid(transform->trffromsql);
                              12862         [ -  + ]:             40 :         if (fromsqlFuncInfo == NULL)
  737 tgl@sss.pgh.pa.us       12863                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              12864                 :                :                      transform->trffromsql);
                              12865                 :                :     }
 3276 peter_e@gmx.net         12866         [ +  - ]:CBC          40 :     if (OidIsValid(transform->trftosql))
                              12867                 :                :     {
                              12868                 :             40 :         tosqlFuncInfo = findFuncByOid(transform->trftosql);
                              12869         [ -  + ]:             40 :         if (tosqlFuncInfo == NULL)
  737 tgl@sss.pgh.pa.us       12870                 :UBC           0 :             pg_fatal("could not find function definition for function with OID %u",
                              12871                 :                :                      transform->trftosql);
                              12872                 :                :     }
                              12873                 :                : 
 3276 peter_e@gmx.net         12874                 :CBC          40 :     defqry = createPQExpBuffer();
                              12875                 :             40 :     delqry = createPQExpBuffer();
                              12876                 :             40 :     labelq = createPQExpBuffer();
 2239 tgl@sss.pgh.pa.us       12877                 :             40 :     transformargs = createPQExpBuffer();
                              12878                 :                : 
 3276 peter_e@gmx.net         12879                 :             40 :     lanname = get_language_name(fout, transform->trflang);
 3209 heikki.linnakangas@i    12880                 :             40 :     transformType = getFormattedTypeName(fout, transform->trftype, zeroAsNone);
                              12881                 :                : 
 3276 peter_e@gmx.net         12882                 :             40 :     appendPQExpBuffer(delqry, "DROP TRANSFORM FOR %s LANGUAGE %s;\n",
                              12883                 :                :                       transformType, lanname);
                              12884                 :                : 
                              12885                 :             40 :     appendPQExpBuffer(defqry, "CREATE TRANSFORM FOR %s LANGUAGE %s (",
                              12886                 :                :                       transformType, lanname);
                              12887                 :                : 
                              12888   [ -  +  -  - ]:             40 :     if (!transform->trffromsql && !transform->trftosql)
 1840 peter@eisentraut.org    12889                 :UBC           0 :         pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero");
                              12890                 :                : 
 3276 peter_e@gmx.net         12891         [ +  - ]:CBC          40 :     if (transform->trffromsql)
                              12892                 :                :     {
                              12893         [ +  - ]:             40 :         if (fromsqlFuncInfo)
                              12894                 :                :         {
                              12895                 :             40 :             char       *fsig = format_function_signature(fout, fromsqlFuncInfo, true);
                              12896                 :                : 
                              12897                 :                :             /*
                              12898                 :                :              * Always qualify the function name (format_function_signature
                              12899                 :                :              * won't qualify it).
                              12900                 :                :              */
                              12901                 :             40 :             appendPQExpBuffer(defqry, "FROM SQL WITH FUNCTION %s.%s",
 2489 tgl@sss.pgh.pa.us       12902                 :             40 :                               fmtId(fromsqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3276 peter_e@gmx.net         12903                 :             40 :             free(fsig);
                              12904                 :                :         }
                              12905                 :                :         else
 1840 peter@eisentraut.org    12906                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trffromsql field");
                              12907                 :                :     }
                              12908                 :                : 
 3276 peter_e@gmx.net         12909         [ +  - ]:CBC          40 :     if (transform->trftosql)
                              12910                 :                :     {
                              12911         [ +  - ]:             40 :         if (transform->trffromsql)
 1746 drowley@postgresql.o    12912                 :             40 :             appendPQExpBufferStr(defqry, ", ");
                              12913                 :                : 
 3276 peter_e@gmx.net         12914         [ +  - ]:             40 :         if (tosqlFuncInfo)
                              12915                 :                :         {
                              12916                 :             40 :             char       *fsig = format_function_signature(fout, tosqlFuncInfo, true);
                              12917                 :                : 
                              12918                 :                :             /*
                              12919                 :                :              * Always qualify the function name (format_function_signature
                              12920                 :                :              * won't qualify it).
                              12921                 :                :              */
                              12922                 :             40 :             appendPQExpBuffer(defqry, "TO SQL WITH FUNCTION %s.%s",
 2489 tgl@sss.pgh.pa.us       12923                 :             40 :                               fmtId(tosqlFuncInfo->dobj.namespace->dobj.name), fsig);
 3276 peter_e@gmx.net         12924                 :             40 :             free(fsig);
                              12925                 :                :         }
                              12926                 :                :         else
 1840 peter@eisentraut.org    12927                 :UBC           0 :             pg_log_warning("bogus value in pg_transform.trftosql field");
                              12928                 :                :     }
                              12929                 :                : 
 1746 drowley@postgresql.o    12930                 :CBC          40 :     appendPQExpBufferStr(defqry, ");\n");
                              12931                 :                : 
 3276 peter_e@gmx.net         12932                 :             40 :     appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s",
                              12933                 :                :                       transformType, lanname);
                              12934                 :                : 
 2239 tgl@sss.pgh.pa.us       12935                 :             40 :     appendPQExpBuffer(transformargs, "FOR %s LANGUAGE %s",
                              12936                 :                :                       transformType, lanname);
                              12937                 :                : 
 3276 peter_e@gmx.net         12938         [ +  + ]:             40 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       12939                 :              2 :         binary_upgrade_extension_member(defqry, &transform->dobj,
                              12940                 :              2 :                                         "TRANSFORM", transformargs->data, NULL);
                              12941                 :                : 
 2930 sfrost@snowman.net      12942         [ +  - ]:             40 :     if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              12943                 :             40 :         ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    12944                 :             40 :                      ARCHIVE_OPTS(.tag = labelq->data,
                              12945                 :                :                                   .description = "TRANSFORM",
                              12946                 :                :                                   .section = SECTION_PRE_DATA,
                              12947                 :                :                                   .createStmt = defqry->data,
                              12948                 :                :                                   .dropStmt = delqry->data,
                              12949                 :                :                                   .deps = transform->dobj.dependencies,
                              12950                 :                :                                   .nDeps = transform->dobj.nDeps));
                              12951                 :                : 
                              12952                 :                :     /* Dump Transform Comments */
 2930 sfrost@snowman.net      12953         [ -  + ]:             40 :     if (transform->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       12954                 :UBC           0 :         dumpComment(fout, "TRANSFORM", transformargs->data,
                              12955                 :                :                     NULL, "",
 2930 sfrost@snowman.net      12956                 :              0 :                     transform->dobj.catId, 0, transform->dobj.dumpId);
                              12957                 :                : 
 3276 peter_e@gmx.net         12958                 :CBC          40 :     free(lanname);
                              12959                 :             40 :     destroyPQExpBuffer(defqry);
                              12960                 :             40 :     destroyPQExpBuffer(delqry);
                              12961                 :             40 :     destroyPQExpBuffer(labelq);
 2239 tgl@sss.pgh.pa.us       12962                 :             40 :     destroyPQExpBuffer(transformargs);
                              12963                 :                : }
                              12964                 :                : 
                              12965                 :                : 
                              12966                 :                : /*
                              12967                 :                :  * dumpOpr
                              12968                 :                :  *    write out a single operator definition
                              12969                 :                :  */
                              12970                 :                : static void
 1159 peter@eisentraut.org    12971                 :            907 : dumpOpr(Archive *fout, const OprInfo *oprinfo)
                              12972                 :                : {
 3014 tgl@sss.pgh.pa.us       12973                 :            907 :     DumpOptions *dopt = fout->dopt;
                              12974                 :                :     PQExpBuffer query;
                              12975                 :                :     PQExpBuffer q;
                              12976                 :                :     PQExpBuffer delq;
                              12977                 :                :     PQExpBuffer oprid;
                              12978                 :                :     PQExpBuffer details;
                              12979                 :                :     PGresult   *res;
                              12980                 :                :     int         i_oprkind;
                              12981                 :                :     int         i_oprcode;
                              12982                 :                :     int         i_oprleft;
                              12983                 :                :     int         i_oprright;
                              12984                 :                :     int         i_oprcom;
                              12985                 :                :     int         i_oprnegate;
                              12986                 :                :     int         i_oprrest;
                              12987                 :                :     int         i_oprjoin;
                              12988                 :                :     int         i_oprcanmerge;
                              12989                 :                :     int         i_oprcanhash;
                              12990                 :                :     char       *oprkind;
                              12991                 :                :     char       *oprcode;
                              12992                 :                :     char       *oprleft;
                              12993                 :                :     char       *oprright;
                              12994                 :                :     char       *oprcom;
                              12995                 :                :     char       *oprnegate;
                              12996                 :                :     char       *oprrest;
                              12997                 :                :     char       *oprjoin;
                              12998                 :                :     char       *oprcanmerge;
                              12999                 :                :     char       *oprcanhash;
                              13000                 :                :     char       *oprregproc;
                              13001                 :                :     char       *oprref;
                              13002                 :                : 
                              13003                 :                :     /* Do nothing in data-only dump */
  860                         13004         [ +  + ]:            907 :     if (dopt->dataOnly)
 7435                         13005                 :              3 :         return;
                              13006                 :                : 
                              13007                 :                :     /*
                              13008                 :                :      * some operators are invalid because they were the result of user
                              13009                 :                :      * defining operators before commutators exist
                              13010                 :                :      */
                              13011         [ +  + ]:            904 :     if (!OidIsValid(oprinfo->oprcode))
                              13012                 :             14 :         return;
                              13013                 :                : 
                              13014                 :            890 :     query = createPQExpBuffer();
                              13015                 :            890 :     q = createPQExpBuffer();
                              13016                 :            890 :     delq = createPQExpBuffer();
                              13017                 :            890 :     oprid = createPQExpBuffer();
                              13018                 :            890 :     details = createPQExpBuffer();
                              13019                 :                : 
  860                         13020         [ +  + ]:            890 :     if (!fout->is_prepared[PREPQUERY_DUMPOPR])
                              13021                 :                :     {
                              13022                 :                :         /* Set up query for operator-specific details */
                              13023                 :             42 :         appendPQExpBufferStr(query,
                              13024                 :                :                              "PREPARE dumpOpr(pg_catalog.oid) AS\n"
                              13025                 :                :                              "SELECT oprkind, "
                              13026                 :                :                              "oprcode::pg_catalog.regprocedure, "
                              13027                 :                :                              "oprleft::pg_catalog.regtype, "
                              13028                 :                :                              "oprright::pg_catalog.regtype, "
                              13029                 :                :                              "oprcom, "
                              13030                 :                :                              "oprnegate, "
                              13031                 :                :                              "oprrest::pg_catalog.regprocedure, "
                              13032                 :                :                              "oprjoin::pg_catalog.regprocedure, "
                              13033                 :                :                              "oprcanmerge, oprcanhash "
                              13034                 :                :                              "FROM pg_catalog.pg_operator "
                              13035                 :                :                              "WHERE oid = $1");
                              13036                 :                : 
                              13037                 :             42 :         ExecuteSqlStatement(fout, query->data);
                              13038                 :                : 
                              13039                 :             42 :         fout->is_prepared[PREPQUERY_DUMPOPR] = true;
                              13040                 :                :     }
                              13041                 :                : 
                              13042                 :            890 :     printfPQExpBuffer(query,
                              13043                 :                :                       "EXECUTE dumpOpr('%u')",
                              13044                 :            890 :                       oprinfo->dobj.catId.oid);
                              13045                 :                : 
 4441 rhaas@postgresql.org    13046                 :            890 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13047                 :                : 
 8010 tgl@sss.pgh.pa.us       13048                 :            890 :     i_oprkind = PQfnumber(res, "oprkind");
                              13049                 :            890 :     i_oprcode = PQfnumber(res, "oprcode");
                              13050                 :            890 :     i_oprleft = PQfnumber(res, "oprleft");
                              13051                 :            890 :     i_oprright = PQfnumber(res, "oprright");
                              13052                 :            890 :     i_oprcom = PQfnumber(res, "oprcom");
                              13053                 :            890 :     i_oprnegate = PQfnumber(res, "oprnegate");
                              13054                 :            890 :     i_oprrest = PQfnumber(res, "oprrest");
                              13055                 :            890 :     i_oprjoin = PQfnumber(res, "oprjoin");
 6322                         13056                 :            890 :     i_oprcanmerge = PQfnumber(res, "oprcanmerge");
 8010                         13057                 :            890 :     i_oprcanhash = PQfnumber(res, "oprcanhash");
                              13058                 :                : 
                              13059                 :            890 :     oprkind = PQgetvalue(res, 0, i_oprkind);
                              13060                 :            890 :     oprcode = PQgetvalue(res, 0, i_oprcode);
                              13061                 :            890 :     oprleft = PQgetvalue(res, 0, i_oprleft);
                              13062                 :            890 :     oprright = PQgetvalue(res, 0, i_oprright);
                              13063                 :            890 :     oprcom = PQgetvalue(res, 0, i_oprcom);
                              13064                 :            890 :     oprnegate = PQgetvalue(res, 0, i_oprnegate);
                              13065                 :            890 :     oprrest = PQgetvalue(res, 0, i_oprrest);
                              13066                 :            890 :     oprjoin = PQgetvalue(res, 0, i_oprjoin);
 6322                         13067                 :            890 :     oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
 8010                         13068                 :            890 :     oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
                              13069                 :                : 
                              13070                 :                :     /* In PG14 upwards postfix operator support does not exist anymore. */
 1305                         13071         [ -  + ]:            890 :     if (strcmp(oprkind, "r") == 0)
 1305 tgl@sss.pgh.pa.us       13072                 :UBC           0 :         pg_log_warning("postfix operators are not supported anymore (operator \"%s\")",
                              13073                 :                :                        oprcode);
                              13074                 :                : 
 1328 peter@eisentraut.org    13075                 :CBC         890 :     oprregproc = convertRegProcReference(oprcode);
 3697 sfrost@snowman.net      13076         [ +  - ]:            890 :     if (oprregproc)
                              13077                 :                :     {
 2069 peter_e@gmx.net         13078                 :            890 :         appendPQExpBuffer(details, "    FUNCTION = %s", oprregproc);
 3697 sfrost@snowman.net      13079                 :            890 :         free(oprregproc);
                              13080                 :                :     }
                              13081                 :                : 
 8010 tgl@sss.pgh.pa.us       13082                 :            890 :     appendPQExpBuffer(oprid, "%s (",
 7347                         13083                 :            890 :                       oprinfo->dobj.name);
                              13084                 :                : 
                              13085                 :                :     /*
                              13086                 :                :      * right unary means there's a left arg and left unary means there's a
                              13087                 :                :      * right arg.  (Although the "r" case is dead code for PG14 and later,
                              13088                 :                :      * continue to support it in case we're dumping from an old server.)
                              13089                 :                :      */
 8010                         13090         [ +  - ]:            890 :     if (strcmp(oprkind, "r") == 0 ||
                              13091         [ +  + ]:            890 :         strcmp(oprkind, "b") == 0)
                              13092                 :                :     {
 2741                         13093                 :            829 :         appendPQExpBuffer(details, ",\n    LEFTARG = %s", oprleft);
                              13094                 :            829 :         appendPQExpBufferStr(oprid, oprleft);
                              13095                 :                :     }
                              13096                 :                :     else
 3800 heikki.linnakangas@i    13097                 :             61 :         appendPQExpBufferStr(oprid, "NONE");
                              13098                 :                : 
 8010 tgl@sss.pgh.pa.us       13099         [ +  + ]:            890 :     if (strcmp(oprkind, "l") == 0 ||
                              13100         [ +  - ]:            829 :         strcmp(oprkind, "b") == 0)
                              13101                 :                :     {
 2741                         13102                 :            890 :         appendPQExpBuffer(details, ",\n    RIGHTARG = %s", oprright);
                              13103                 :            890 :         appendPQExpBuffer(oprid, ", %s)", oprright);
                              13104                 :                :     }
                              13105                 :                :     else
 3800 heikki.linnakangas@i    13106                 :UBC           0 :         appendPQExpBufferStr(oprid, ", NONE)");
                              13107                 :                : 
 1328 peter@eisentraut.org    13108                 :CBC         890 :     oprref = getFormattedOperatorName(oprcom);
 3697 sfrost@snowman.net      13109         [ +  + ]:            890 :     if (oprref)
                              13110                 :                :     {
                              13111                 :            567 :         appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
                              13112                 :            567 :         free(oprref);
                              13113                 :                :     }
                              13114                 :                : 
 1328 peter@eisentraut.org    13115                 :            890 :     oprref = getFormattedOperatorName(oprnegate);
 3697 sfrost@snowman.net      13116         [ +  + ]:            890 :     if (oprref)
                              13117                 :                :     {
                              13118                 :            391 :         appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
                              13119                 :            391 :         free(oprref);
                              13120                 :                :     }
                              13121                 :                : 
 6322 tgl@sss.pgh.pa.us       13122         [ +  + ]:            890 :     if (strcmp(oprcanmerge, "t") == 0)
 3800 heikki.linnakangas@i    13123                 :             75 :         appendPQExpBufferStr(details, ",\n    MERGES");
                              13124                 :                : 
 8010 tgl@sss.pgh.pa.us       13125         [ +  + ]:            890 :     if (strcmp(oprcanhash, "t") == 0)
 3800 heikki.linnakangas@i    13126                 :             46 :         appendPQExpBufferStr(details, ",\n    HASHES");
                              13127                 :                : 
 1328 peter@eisentraut.org    13128                 :            890 :     oprregproc = convertRegProcReference(oprrest);
 3697 sfrost@snowman.net      13129         [ +  + ]:            890 :     if (oprregproc)
                              13130                 :                :     {
                              13131                 :            518 :         appendPQExpBuffer(details, ",\n    RESTRICT = %s", oprregproc);
                              13132                 :            518 :         free(oprregproc);
                              13133                 :                :     }
                              13134                 :                : 
 1328 peter@eisentraut.org    13135                 :            890 :     oprregproc = convertRegProcReference(oprjoin);
 3697 sfrost@snowman.net      13136         [ +  + ]:            890 :     if (oprregproc)
                              13137                 :                :     {
                              13138                 :            518 :         appendPQExpBuffer(details, ",\n    JOIN = %s", oprregproc);
                              13139                 :            518 :         free(oprregproc);
                              13140                 :                :     }
                              13141                 :                : 
 7992 tgl@sss.pgh.pa.us       13142                 :            890 :     appendPQExpBuffer(delq, "DROP OPERATOR %s.%s;\n",
 7347                         13143                 :            890 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
                              13144                 :                :                       oprid->data);
                              13145                 :                : 
 2239                         13146                 :            890 :     appendPQExpBuffer(q, "CREATE OPERATOR %s.%s (\n%s\n);\n",
                              13147                 :            890 :                       fmtId(oprinfo->dobj.namespace->dobj.name),
 7347                         13148                 :            890 :                       oprinfo->dobj.name, details->data);
                              13149                 :                : 
 3470 alvherre@alvh.no-ip.    13150         [ +  + ]:            890 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       13151                 :             12 :         binary_upgrade_extension_member(q, &oprinfo->dobj,
                              13152                 :             12 :                                         "OPERATOR", oprid->data,
                              13153                 :             12 :                                         oprinfo->dobj.namespace->dobj.name);
                              13154                 :                : 
 2930 sfrost@snowman.net      13155         [ +  - ]:            890 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13156                 :            890 :         ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    13157                 :            890 :                      ARCHIVE_OPTS(.tag = oprinfo->dobj.name,
                              13158                 :                :                                   .namespace = oprinfo->dobj.namespace->dobj.name,
                              13159                 :                :                                   .owner = oprinfo->rolname,
                              13160                 :                :                                   .description = "OPERATOR",
                              13161                 :                :                                   .section = SECTION_PRE_DATA,
                              13162                 :                :                                   .createStmt = q->data,
                              13163                 :                :                                   .dropStmt = delq->data));
                              13164                 :                : 
                              13165                 :                :     /* Dump Operator Comments */
 2930 sfrost@snowman.net      13166         [ +  + ]:            890 :     if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       13167                 :            799 :         dumpComment(fout, "OPERATOR", oprid->data,
 2930 sfrost@snowman.net      13168                 :            799 :                     oprinfo->dobj.namespace->dobj.name, oprinfo->rolname,
                              13169                 :            799 :                     oprinfo->dobj.catId, 0, oprinfo->dobj.dumpId);
                              13170                 :                : 
 8010 tgl@sss.pgh.pa.us       13171                 :            890 :     PQclear(res);
                              13172                 :                : 
                              13173                 :            890 :     destroyPQExpBuffer(query);
                              13174                 :            890 :     destroyPQExpBuffer(q);
                              13175                 :            890 :     destroyPQExpBuffer(delq);
                              13176                 :            890 :     destroyPQExpBuffer(oprid);
                              13177                 :            890 :     destroyPQExpBuffer(details);
                              13178                 :                : }
                              13179                 :                : 
                              13180                 :                : /*
                              13181                 :                :  * Convert a function reference obtained from pg_operator
                              13182                 :                :  *
                              13183                 :                :  * Returns allocated string of what to print, or NULL if function references
                              13184                 :                :  * is InvalidOid. Returned string is expected to be free'd by the caller.
                              13185                 :                :  *
                              13186                 :                :  * The input is a REGPROCEDURE display; we have to strip the argument-types
                              13187                 :                :  * part.
                              13188                 :                :  */
                              13189                 :                : static char *
 1328 peter@eisentraut.org    13190                 :           2670 : convertRegProcReference(const char *proc)
                              13191                 :                : {
                              13192                 :                :     char       *name;
                              13193                 :                :     char       *paren;
                              13194                 :                :     bool        inquote;
                              13195                 :                : 
                              13196                 :                :     /* In all cases "-" means a null reference */
 8010 tgl@sss.pgh.pa.us       13197         [ +  + ]:           2670 :     if (strcmp(proc, "-") == 0)
                              13198                 :            744 :         return NULL;
                              13199                 :                : 
 2741                         13200                 :           1926 :     name = pg_strdup(proc);
                              13201                 :                :     /* find non-double-quoted left paren */
                              13202                 :           1926 :     inquote = false;
                              13203         [ +  - ]:          23128 :     for (paren = name; *paren; paren++)
                              13204                 :                :     {
                              13205   [ +  +  +  - ]:          23128 :         if (*paren == '(' && !inquote)
                              13206                 :                :         {
                              13207                 :           1926 :             *paren = '\0';
                              13208                 :           1926 :             break;
                              13209                 :                :         }
                              13210         [ +  + ]:          21202 :         if (*paren == '"')
                              13211                 :             50 :             inquote = !inquote;
                              13212                 :                :     }
                              13213                 :           1926 :     return name;
                              13214                 :                : }
                              13215                 :                : 
                              13216                 :                : /*
                              13217                 :                :  * getFormattedOperatorName - retrieve the operator name for the
                              13218                 :                :  * given operator OID (presented in string form).
                              13219                 :                :  *
                              13220                 :                :  * Returns an allocated string, or NULL if the given OID is invalid.
                              13221                 :                :  * Caller is responsible for free'ing result string.
                              13222                 :                :  *
                              13223                 :                :  * What we produce has the format "OPERATOR(schema.oprname)".  This is only
                              13224                 :                :  * useful in commands where the operator's argument types can be inferred from
                              13225                 :                :  * context.  We always schema-qualify the name, though.  The predecessor to
                              13226                 :                :  * this code tried to skip the schema qualification if possible, but that led
                              13227                 :                :  * to wrong results in corner cases, such as if an operator and its negator
                              13228                 :                :  * are in different schemas.
                              13229                 :                :  */
                              13230                 :                : static char *
 1328 peter@eisentraut.org    13231                 :           2069 : getFormattedOperatorName(const char *oproid)
                              13232                 :                : {
                              13233                 :                :     OprInfo    *oprInfo;
                              13234                 :                : 
                              13235                 :                :     /* In all cases "0" means a null reference */
 2239 tgl@sss.pgh.pa.us       13236         [ +  + ]:           2069 :     if (strcmp(oproid, "0") == 0)
 8010                         13237                 :           1111 :         return NULL;
                              13238                 :                : 
 2239                         13239                 :            958 :     oprInfo = findOprByOid(atooid(oproid));
                              13240         [ -  + ]:            958 :     if (oprInfo == NULL)
                              13241                 :                :     {
 1840 peter@eisentraut.org    13242                 :UBC           0 :         pg_log_warning("could not find operator with OID %s",
                              13243                 :                :                        oproid);
 2239 tgl@sss.pgh.pa.us       13244                 :              0 :         return NULL;
                              13245                 :                :     }
                              13246                 :                : 
 2239 tgl@sss.pgh.pa.us       13247                 :CBC         958 :     return psprintf("OPERATOR(%s.%s)",
                              13248                 :            958 :                     fmtId(oprInfo->dobj.namespace->dobj.name),
                              13249                 :                :                     oprInfo->dobj.name);
                              13250                 :                : }
                              13251                 :                : 
                              13252                 :                : /*
                              13253                 :                :  * Convert a function OID obtained from pg_ts_parser or pg_ts_template
                              13254                 :                :  *
                              13255                 :                :  * It is sufficient to use REGPROC rather than REGPROCEDURE, since the
                              13256                 :                :  * argument lists of these functions are predetermined.  Note that the
                              13257                 :                :  * caller should ensure we are in the proper schema, because the results
                              13258                 :                :  * are search path dependent!
                              13259                 :                :  */
                              13260                 :                : static char *
 4450 rhaas@postgresql.org    13261                 :            195 : convertTSFunction(Archive *fout, Oid funcOid)
                              13262                 :                : {
                              13263                 :                :     char       *result;
                              13264                 :                :     char        query[128];
                              13265                 :                :     PGresult   *res;
                              13266                 :                : 
 6081 tgl@sss.pgh.pa.us       13267                 :            195 :     snprintf(query, sizeof(query),
                              13268                 :                :              "SELECT '%u'::pg_catalog.regproc", funcOid);
 4441 rhaas@postgresql.org    13269                 :            195 :     res = ExecuteSqlQueryForSingleRow(fout, query);
                              13270                 :                : 
 4524 bruce@momjian.us        13271                 :            195 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              13272                 :                : 
 6081 tgl@sss.pgh.pa.us       13273                 :            195 :     PQclear(res);
                              13274                 :                : 
                              13275                 :            195 :     return result;
                              13276                 :                : }
                              13277                 :                : 
                              13278                 :                : /*
                              13279                 :                :  * dumpAccessMethod
                              13280                 :                :  *    write out a single access method definition
                              13281                 :                :  */
                              13282                 :                : static void
 1159 peter@eisentraut.org    13283                 :             82 : dumpAccessMethod(Archive *fout, const AccessMethodInfo *aminfo)
                              13284                 :                : {
 2944 alvherre@alvh.no-ip.    13285                 :             82 :     DumpOptions *dopt = fout->dopt;
                              13286                 :                :     PQExpBuffer q;
                              13287                 :                :     PQExpBuffer delq;
                              13288                 :                :     char       *qamname;
                              13289                 :                : 
                              13290                 :                :     /* Do nothing in data-only dump */
  860 tgl@sss.pgh.pa.us       13291         [ +  + ]:             82 :     if (dopt->dataOnly)
 2944 alvherre@alvh.no-ip.    13292                 :              6 :         return;
                              13293                 :                : 
                              13294                 :             76 :     q = createPQExpBuffer();
                              13295                 :             76 :     delq = createPQExpBuffer();
                              13296                 :                : 
                              13297                 :             76 :     qamname = pg_strdup(fmtId(aminfo->dobj.name));
                              13298                 :                : 
                              13299                 :             76 :     appendPQExpBuffer(q, "CREATE ACCESS METHOD %s ", qamname);
                              13300                 :                : 
                              13301      [ +  +  - ]:             76 :     switch (aminfo->amtype)
                              13302                 :                :     {
                              13303                 :             36 :         case AMTYPE_INDEX:
 1746 drowley@postgresql.o    13304                 :             36 :             appendPQExpBufferStr(q, "TYPE INDEX ");
 2944 alvherre@alvh.no-ip.    13305                 :             36 :             break;
 1866 andres@anarazel.de      13306                 :             40 :         case AMTYPE_TABLE:
 1746 drowley@postgresql.o    13307                 :             40 :             appendPQExpBufferStr(q, "TYPE TABLE ");
 1866 andres@anarazel.de      13308                 :             40 :             break;
 2944 alvherre@alvh.no-ip.    13309                 :UBC           0 :         default:
 1840 peter@eisentraut.org    13310                 :              0 :             pg_log_warning("invalid type \"%c\" of access method \"%s\"",
                              13311                 :                :                            aminfo->amtype, qamname);
 2944 alvherre@alvh.no-ip.    13312                 :              0 :             destroyPQExpBuffer(q);
                              13313                 :              0 :             destroyPQExpBuffer(delq);
 2239 tgl@sss.pgh.pa.us       13314                 :              0 :             free(qamname);
 2944 alvherre@alvh.no-ip.    13315                 :              0 :             return;
                              13316                 :                :     }
                              13317                 :                : 
 2944 alvherre@alvh.no-ip.    13318                 :CBC          76 :     appendPQExpBuffer(q, "HANDLER %s;\n", aminfo->amhandler);
                              13319                 :                : 
                              13320                 :             76 :     appendPQExpBuffer(delq, "DROP ACCESS METHOD %s;\n",
                              13321                 :                :                       qamname);
                              13322                 :                : 
 2751 tgl@sss.pgh.pa.us       13323         [ +  + ]:             76 :     if (dopt->binary_upgrade)
 2239                         13324                 :              4 :         binary_upgrade_extension_member(q, &aminfo->dobj,
                              13325                 :                :                                         "ACCESS METHOD", qamname, NULL);
                              13326                 :                : 
 2868 sfrost@snowman.net      13327         [ +  - ]:             76 :     if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13328                 :             76 :         ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    13329                 :             76 :                      ARCHIVE_OPTS(.tag = aminfo->dobj.name,
                              13330                 :                :                                   .description = "ACCESS METHOD",
                              13331                 :                :                                   .section = SECTION_PRE_DATA,
                              13332                 :                :                                   .createStmt = q->data,
                              13333                 :                :                                   .dropStmt = delq->data));
                              13334                 :                : 
                              13335                 :                :     /* Dump Access Method Comments */
 2868 sfrost@snowman.net      13336         [ -  + ]:             76 :     if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       13337                 :UBC           0 :         dumpComment(fout, "ACCESS METHOD", qamname,
                              13338                 :                :                     NULL, "",
 2868 sfrost@snowman.net      13339                 :              0 :                     aminfo->dobj.catId, 0, aminfo->dobj.dumpId);
                              13340                 :                : 
 2944 alvherre@alvh.no-ip.    13341                 :CBC          76 :     destroyPQExpBuffer(q);
                              13342                 :             76 :     destroyPQExpBuffer(delq);
 2239 tgl@sss.pgh.pa.us       13343                 :             76 :     free(qamname);
                              13344                 :                : }
                              13345                 :                : 
                              13346                 :                : /*
                              13347                 :                :  * dumpOpclass
                              13348                 :                :  *    write out a single operator class definition
                              13349                 :                :  */
                              13350                 :                : static void
 1159 peter@eisentraut.org    13351                 :            309 : dumpOpclass(Archive *fout, const OpclassInfo *opcinfo)
                              13352                 :                : {
 3014 tgl@sss.pgh.pa.us       13353                 :            309 :     DumpOptions *dopt = fout->dopt;
                              13354                 :                :     PQExpBuffer query;
                              13355                 :                :     PQExpBuffer q;
                              13356                 :                :     PQExpBuffer delq;
                              13357                 :                :     PQExpBuffer nameusing;
                              13358                 :                :     PGresult   *res;
                              13359                 :                :     int         ntups;
                              13360                 :                :     int         i_opcintype;
                              13361                 :                :     int         i_opckeytype;
                              13362                 :                :     int         i_opcdefault;
                              13363                 :                :     int         i_opcfamily;
                              13364                 :                :     int         i_opcfamilyname;
                              13365                 :                :     int         i_opcfamilynsp;
                              13366                 :                :     int         i_amname;
                              13367                 :                :     int         i_amopstrategy;
                              13368                 :                :     int         i_amopopr;
                              13369                 :                :     int         i_sortfamily;
                              13370                 :                :     int         i_sortfamilynsp;
                              13371                 :                :     int         i_amprocnum;
                              13372                 :                :     int         i_amproc;
                              13373                 :                :     int         i_amproclefttype;
                              13374                 :                :     int         i_amprocrighttype;
                              13375                 :                :     char       *opcintype;
                              13376                 :                :     char       *opckeytype;
                              13377                 :                :     char       *opcdefault;
                              13378                 :                :     char       *opcfamily;
                              13379                 :                :     char       *opcfamilyname;
                              13380                 :                :     char       *opcfamilynsp;
                              13381                 :                :     char       *amname;
                              13382                 :                :     char       *amopstrategy;
                              13383                 :                :     char       *amopopr;
                              13384                 :                :     char       *sortfamily;
                              13385                 :                :     char       *sortfamilynsp;
                              13386                 :                :     char       *amprocnum;
                              13387                 :                :     char       *amproc;
                              13388                 :                :     char       *amproclefttype;
                              13389                 :                :     char       *amprocrighttype;
                              13390                 :                :     bool        needComma;
                              13391                 :                :     int         i;
                              13392                 :                : 
                              13393                 :                :     /* Do nothing in data-only dump */
  860                         13394         [ +  + ]:            309 :     if (dopt->dataOnly)
 7435                         13395                 :              9 :         return;
                              13396                 :                : 
                              13397                 :            300 :     query = createPQExpBuffer();
                              13398                 :            300 :     q = createPQExpBuffer();
                              13399                 :            300 :     delq = createPQExpBuffer();
 2239                         13400                 :            300 :     nameusing = createPQExpBuffer();
                              13401                 :                : 
                              13402                 :                :     /* Get additional fields from the pg_opclass row */
  852                         13403                 :            300 :     appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                              13404                 :                :                       "opckeytype::pg_catalog.regtype, "
                              13405                 :                :                       "opcdefault, opcfamily, "
                              13406                 :                :                       "opfname AS opcfamilyname, "
                              13407                 :                :                       "nspname AS opcfamilynsp, "
                              13408                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opcmethod) AS amname "
                              13409                 :                :                       "FROM pg_catalog.pg_opclass c "
                              13410                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = opcfamily "
                              13411                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              13412                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              13413                 :            300 :                       opcinfo->dobj.catId.oid);
                              13414                 :                : 
 4441 rhaas@postgresql.org    13415                 :            300 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13416                 :                : 
 7929 tgl@sss.pgh.pa.us       13417                 :            300 :     i_opcintype = PQfnumber(res, "opcintype");
                              13418                 :            300 :     i_opckeytype = PQfnumber(res, "opckeytype");
                              13419                 :            300 :     i_opcdefault = PQfnumber(res, "opcdefault");
 6291                         13420                 :            300 :     i_opcfamily = PQfnumber(res, "opcfamily");
 4890                         13421                 :            300 :     i_opcfamilyname = PQfnumber(res, "opcfamilyname");
 6291                         13422                 :            300 :     i_opcfamilynsp = PQfnumber(res, "opcfamilynsp");
 7929                         13423                 :            300 :     i_amname = PQfnumber(res, "amname");
                              13424                 :                : 
                              13425                 :                :     /* opcintype may still be needed after we PQclear res */
 2515                         13426                 :            300 :     opcintype = pg_strdup(PQgetvalue(res, 0, i_opcintype));
 7929                         13427                 :            300 :     opckeytype = PQgetvalue(res, 0, i_opckeytype);
                              13428                 :            300 :     opcdefault = PQgetvalue(res, 0, i_opcdefault);
                              13429                 :                :     /* opcfamily will still be needed after we PQclear res */
 4524 bruce@momjian.us        13430                 :            300 :     opcfamily = pg_strdup(PQgetvalue(res, 0, i_opcfamily));
 4890 tgl@sss.pgh.pa.us       13431                 :            300 :     opcfamilyname = PQgetvalue(res, 0, i_opcfamilyname);
 6291                         13432                 :            300 :     opcfamilynsp = PQgetvalue(res, 0, i_opcfamilynsp);
                              13433                 :                :     /* amname will still be needed after we PQclear res */
 4524 bruce@momjian.us        13434                 :            300 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              13435                 :                : 
 7929 tgl@sss.pgh.pa.us       13436                 :            300 :     appendPQExpBuffer(delq, "DROP OPERATOR CLASS %s",
 2239                         13437                 :            300 :                       fmtQualifiedDumpable(opcinfo));
 7929                         13438                 :            300 :     appendPQExpBuffer(delq, " USING %s;\n",
                              13439                 :                :                       fmtId(amname));
                              13440                 :                : 
                              13441                 :                :     /* Build the fixed portion of the CREATE command */
 7910 peter_e@gmx.net         13442                 :            300 :     appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
 2239 tgl@sss.pgh.pa.us       13443                 :            300 :                       fmtQualifiedDumpable(opcinfo));
 7929                         13444         [ +  + ]:            300 :     if (strcmp(opcdefault, "t") == 0)
 3800 heikki.linnakangas@i    13445                 :            119 :         appendPQExpBufferStr(q, "DEFAULT ");
 6291 tgl@sss.pgh.pa.us       13446                 :            300 :     appendPQExpBuffer(q, "FOR TYPE %s USING %s",
                              13447                 :                :                       opcintype,
                              13448                 :                :                       fmtId(amname));
 2923                         13449         [ +  - ]:            300 :     if (strlen(opcfamilyname) > 0)
                              13450                 :                :     {
 3800 heikki.linnakangas@i    13451                 :            300 :         appendPQExpBufferStr(q, " FAMILY ");
 2239 tgl@sss.pgh.pa.us       13452                 :            300 :         appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
 3209 heikki.linnakangas@i    13453                 :            300 :         appendPQExpBufferStr(q, fmtId(opcfamilyname));
                              13454                 :                :     }
 3800                         13455                 :            300 :     appendPQExpBufferStr(q, " AS\n    ");
                              13456                 :                : 
 7929 tgl@sss.pgh.pa.us       13457                 :            300 :     needComma = false;
                              13458                 :                : 
                              13459         [ +  + ]:            300 :     if (strcmp(opckeytype, "-") != 0)
                              13460                 :                :     {
 7910 peter_e@gmx.net         13461                 :             84 :         appendPQExpBuffer(q, "STORAGE %s",
                              13462                 :                :                           opckeytype);
 7929 tgl@sss.pgh.pa.us       13463                 :             84 :         needComma = true;
                              13464                 :                :     }
                              13465                 :                : 
                              13466                 :            300 :     PQclear(res);
                              13467                 :                : 
                              13468                 :                :     /*
                              13469                 :                :      * Now fetch and print the OPERATOR entries (pg_amop rows).
                              13470                 :                :      *
                              13471                 :                :      * Print only those opfamily members that are tied to the opclass by
                              13472                 :                :      * pg_depend entries.
                              13473                 :                :      */
                              13474                 :            300 :     resetPQExpBuffer(query);
  852                         13475                 :            300 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              13476                 :                :                       "amopopr::pg_catalog.regoperator, "
                              13477                 :                :                       "opfname AS sortfamily, "
                              13478                 :                :                       "nspname AS sortfamilynsp "
                              13479                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              13480                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              13481                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              13482                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              13483                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              13484                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              13485                 :                :                       "AND amopfamily = '%s'::pg_catalog.oid "
                              13486                 :                :                       "ORDER BY amopstrategy",
                              13487                 :            300 :                       opcinfo->dobj.catId.oid,
                              13488                 :                :                       opcfamily);
                              13489                 :                : 
 4450 rhaas@postgresql.org    13490                 :            300 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              13491                 :                : 
 7929 tgl@sss.pgh.pa.us       13492                 :            300 :     ntups = PQntuples(res);
                              13493                 :                : 
                              13494                 :            300 :     i_amopstrategy = PQfnumber(res, "amopstrategy");
                              13495                 :            300 :     i_amopopr = PQfnumber(res, "amopopr");
 4890                         13496                 :            300 :     i_sortfamily = PQfnumber(res, "sortfamily");
                              13497                 :            300 :     i_sortfamilynsp = PQfnumber(res, "sortfamilynsp");
                              13498                 :                : 
 7929                         13499         [ +  + ]:            526 :     for (i = 0; i < ntups; i++)
                              13500                 :                :     {
                              13501                 :            226 :         amopstrategy = PQgetvalue(res, i, i_amopstrategy);
                              13502                 :            226 :         amopopr = PQgetvalue(res, i, i_amopopr);
 4890                         13503                 :            226 :         sortfamily = PQgetvalue(res, i, i_sortfamily);
                              13504                 :            226 :         sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
                              13505                 :                : 
 7929                         13506         [ +  + ]:            226 :         if (needComma)
 3800 heikki.linnakangas@i    13507                 :            144 :             appendPQExpBufferStr(q, " ,\n    ");
                              13508                 :                : 
 7910 peter_e@gmx.net         13509                 :            226 :         appendPQExpBuffer(q, "OPERATOR %s %s",
                              13510                 :                :                           amopstrategy, amopopr);
                              13511                 :                : 
 4890 tgl@sss.pgh.pa.us       13512         [ -  + ]:            226 :         if (strlen(sortfamily) > 0)
                              13513                 :                :         {
 3800 heikki.linnakangas@i    13514                 :UBC           0 :             appendPQExpBufferStr(q, " FOR ORDER BY ");
 2239 tgl@sss.pgh.pa.us       13515                 :              0 :             appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 3800 heikki.linnakangas@i    13516                 :              0 :             appendPQExpBufferStr(q, fmtId(sortfamily));
                              13517                 :                :         }
                              13518                 :                : 
 7929 tgl@sss.pgh.pa.us       13519                 :CBC         226 :         needComma = true;
                              13520                 :                :     }
                              13521                 :                : 
                              13522                 :            300 :     PQclear(res);
                              13523                 :                : 
                              13524                 :                :     /*
                              13525                 :                :      * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              13526                 :                :      *
                              13527                 :                :      * Print only those opfamily members that are tied to the opclass by
                              13528                 :                :      * pg_depend entries.
                              13529                 :                :      *
                              13530                 :                :      * We print the amproclefttype/amprocrighttype even though in most cases
                              13531                 :                :      * the backend could deduce the right values, because of the corner case
                              13532                 :                :      * of a btree sort support function for a cross-type comparison.
                              13533                 :                :      */
                              13534                 :            300 :     resetPQExpBuffer(query);
                              13535                 :                : 
  852                         13536                 :            300 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              13537                 :                :                       "amproc::pg_catalog.regprocedure, "
                              13538                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              13539                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              13540                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              13541                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opclass'::pg_catalog.regclass "
                              13542                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              13543                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              13544                 :                :                       "AND objid = ap.oid "
                              13545                 :                :                       "ORDER BY amprocnum",
                              13546                 :            300 :                       opcinfo->dobj.catId.oid);
                              13547                 :                : 
 4450 rhaas@postgresql.org    13548                 :            300 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              13549                 :                : 
 7929 tgl@sss.pgh.pa.us       13550                 :            300 :     ntups = PQntuples(res);
                              13551                 :                : 
                              13552                 :            300 :     i_amprocnum = PQfnumber(res, "amprocnum");
                              13553                 :            300 :     i_amproc = PQfnumber(res, "amproc");
 4512                         13554                 :            300 :     i_amproclefttype = PQfnumber(res, "amproclefttype");
                              13555                 :            300 :     i_amprocrighttype = PQfnumber(res, "amprocrighttype");
                              13556                 :                : 
 7929                         13557         [ +  + ]:            336 :     for (i = 0; i < ntups; i++)
                              13558                 :                :     {
                              13559                 :             36 :         amprocnum = PQgetvalue(res, i, i_amprocnum);
                              13560                 :             36 :         amproc = PQgetvalue(res, i, i_amproc);
 4512                         13561                 :             36 :         amproclefttype = PQgetvalue(res, i, i_amproclefttype);
                              13562                 :             36 :         amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
                              13563                 :                : 
 7929                         13564         [ +  - ]:             36 :         if (needComma)
 3800 heikki.linnakangas@i    13565                 :             36 :             appendPQExpBufferStr(q, " ,\n    ");
                              13566                 :                : 
 4512 tgl@sss.pgh.pa.us       13567                 :             36 :         appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
                              13568                 :                : 
                              13569   [ +  -  +  - ]:             36 :         if (*amproclefttype && *amprocrighttype)
                              13570                 :             36 :             appendPQExpBuffer(q, " (%s, %s)", amproclefttype, amprocrighttype);
                              13571                 :                : 
                              13572                 :             36 :         appendPQExpBuffer(q, " %s", amproc);
                              13573                 :                : 
 7929                         13574                 :             36 :         needComma = true;
                              13575                 :                :     }
                              13576                 :                : 
                              13577                 :            300 :     PQclear(res);
                              13578                 :                : 
                              13579                 :                :     /*
                              13580                 :                :      * If needComma is still false it means we haven't added anything after
                              13581                 :                :      * the AS keyword.  To avoid printing broken SQL, append a dummy STORAGE
                              13582                 :                :      * clause with the same datatype.  This isn't sanctioned by the
                              13583                 :                :      * documentation, but actually DefineOpClass will treat it as a no-op.
                              13584                 :                :      */
 2515                         13585         [ +  + ]:            300 :     if (!needComma)
                              13586                 :            134 :         appendPQExpBuffer(q, "STORAGE %s", opcintype);
                              13587                 :                : 
 3800 heikki.linnakangas@i    13588                 :            300 :     appendPQExpBufferStr(q, ";\n");
                              13589                 :                : 
 2239 tgl@sss.pgh.pa.us       13590                 :            300 :     appendPQExpBufferStr(nameusing, fmtId(opcinfo->dobj.name));
                              13591                 :            300 :     appendPQExpBuffer(nameusing, " USING %s",
                              13592                 :                :                       fmtId(amname));
                              13593                 :                : 
 3470 alvherre@alvh.no-ip.    13594         [ +  + ]:            300 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       13595                 :              6 :         binary_upgrade_extension_member(q, &opcinfo->dobj,
                              13596                 :              6 :                                         "OPERATOR CLASS", nameusing->data,
                              13597                 :              6 :                                         opcinfo->dobj.namespace->dobj.name);
                              13598                 :                : 
 2930 sfrost@snowman.net      13599         [ +  - ]:            300 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13600                 :            300 :         ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    13601                 :            300 :                      ARCHIVE_OPTS(.tag = opcinfo->dobj.name,
                              13602                 :                :                                   .namespace = opcinfo->dobj.namespace->dobj.name,
                              13603                 :                :                                   .owner = opcinfo->rolname,
                              13604                 :                :                                   .description = "OPERATOR CLASS",
                              13605                 :                :                                   .section = SECTION_PRE_DATA,
                              13606                 :                :                                   .createStmt = q->data,
                              13607                 :                :                                   .dropStmt = delq->data));
                              13608                 :                : 
                              13609                 :                :     /* Dump Operator Class Comments */
 2930 sfrost@snowman.net      13610         [ -  + ]:            300 :     if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       13611                 :UBC           0 :         dumpComment(fout, "OPERATOR CLASS", nameusing->data,
 2596                         13612                 :              0 :                     opcinfo->dobj.namespace->dobj.name, opcinfo->rolname,
 2930 sfrost@snowman.net      13613                 :              0 :                     opcinfo->dobj.catId, 0, opcinfo->dobj.dumpId);
                              13614                 :                : 
 2515 tgl@sss.pgh.pa.us       13615                 :CBC         300 :     free(opcintype);
                              13616                 :            300 :     free(opcfamily);
 7450                         13617                 :            300 :     free(amname);
 7929                         13618                 :            300 :     destroyPQExpBuffer(query);
                              13619                 :            300 :     destroyPQExpBuffer(q);
                              13620                 :            300 :     destroyPQExpBuffer(delq);
 2239                         13621                 :            300 :     destroyPQExpBuffer(nameusing);
                              13622                 :                : }
                              13623                 :                : 
                              13624                 :                : /*
                              13625                 :                :  * dumpOpfamily
                              13626                 :                :  *    write out a single operator family definition
                              13627                 :                :  *
                              13628                 :                :  * Note: this also dumps any "loose" operator members that aren't bound to a
                              13629                 :                :  * specific opclass within the opfamily.
                              13630                 :                :  */
                              13631                 :                : static void
 1159 peter@eisentraut.org    13632                 :            259 : dumpOpfamily(Archive *fout, const OpfamilyInfo *opfinfo)
                              13633                 :                : {
 3014 tgl@sss.pgh.pa.us       13634                 :            259 :     DumpOptions *dopt = fout->dopt;
                              13635                 :                :     PQExpBuffer query;
                              13636                 :                :     PQExpBuffer q;
                              13637                 :                :     PQExpBuffer delq;
                              13638                 :                :     PQExpBuffer nameusing;
                              13639                 :                :     PGresult   *res;
                              13640                 :                :     PGresult   *res_ops;
                              13641                 :                :     PGresult   *res_procs;
                              13642                 :                :     int         ntups;
                              13643                 :                :     int         i_amname;
                              13644                 :                :     int         i_amopstrategy;
                              13645                 :                :     int         i_amopopr;
                              13646                 :                :     int         i_sortfamily;
                              13647                 :                :     int         i_sortfamilynsp;
                              13648                 :                :     int         i_amprocnum;
                              13649                 :                :     int         i_amproc;
                              13650                 :                :     int         i_amproclefttype;
                              13651                 :                :     int         i_amprocrighttype;
                              13652                 :                :     char       *amname;
                              13653                 :                :     char       *amopstrategy;
                              13654                 :                :     char       *amopopr;
                              13655                 :                :     char       *sortfamily;
                              13656                 :                :     char       *sortfamilynsp;
                              13657                 :                :     char       *amprocnum;
                              13658                 :                :     char       *amproc;
                              13659                 :                :     char       *amproclefttype;
                              13660                 :                :     char       *amprocrighttype;
                              13661                 :                :     bool        needComma;
                              13662                 :                :     int         i;
                              13663                 :                : 
                              13664                 :                :     /* Do nothing in data-only dump */
  860                         13665         [ +  + ]:            259 :     if (dopt->dataOnly)
 6291                         13666                 :              6 :         return;
                              13667                 :                : 
                              13668                 :            253 :     query = createPQExpBuffer();
                              13669                 :            253 :     q = createPQExpBuffer();
                              13670                 :            253 :     delq = createPQExpBuffer();
 2239                         13671                 :            253 :     nameusing = createPQExpBuffer();
                              13672                 :                : 
                              13673                 :                :     /*
                              13674                 :                :      * Fetch only those opfamily members that are tied directly to the
                              13675                 :                :      * opfamily by pg_depend entries.
                              13676                 :                :      */
  852                         13677                 :            253 :     appendPQExpBuffer(query, "SELECT amopstrategy, "
                              13678                 :                :                       "amopopr::pg_catalog.regoperator, "
                              13679                 :                :                       "opfname AS sortfamily, "
                              13680                 :                :                       "nspname AS sortfamilynsp "
                              13681                 :                :                       "FROM pg_catalog.pg_amop ao JOIN pg_catalog.pg_depend ON "
                              13682                 :                :                       "(classid = 'pg_catalog.pg_amop'::pg_catalog.regclass AND objid = ao.oid) "
                              13683                 :                :                       "LEFT JOIN pg_catalog.pg_opfamily f ON f.oid = amopsortfamily "
                              13684                 :                :                       "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = opfnamespace "
                              13685                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              13686                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              13687                 :                :                       "AND amopfamily = '%u'::pg_catalog.oid "
                              13688                 :                :                       "ORDER BY amopstrategy",
                              13689                 :            253 :                       opfinfo->dobj.catId.oid,
                              13690                 :            253 :                       opfinfo->dobj.catId.oid);
                              13691                 :                : 
 4450 rhaas@postgresql.org    13692                 :            253 :     res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              13693                 :                : 
 6291 tgl@sss.pgh.pa.us       13694                 :            253 :     resetPQExpBuffer(query);
                              13695                 :                : 
                              13696                 :            253 :     appendPQExpBuffer(query, "SELECT amprocnum, "
                              13697                 :                :                       "amproc::pg_catalog.regprocedure, "
                              13698                 :                :                       "amproclefttype::pg_catalog.regtype, "
                              13699                 :                :                       "amprocrighttype::pg_catalog.regtype "
                              13700                 :                :                       "FROM pg_catalog.pg_amproc ap, pg_catalog.pg_depend "
                              13701                 :                :                       "WHERE refclassid = 'pg_catalog.pg_opfamily'::pg_catalog.regclass "
                              13702                 :                :                       "AND refobjid = '%u'::pg_catalog.oid "
                              13703                 :                :                       "AND classid = 'pg_catalog.pg_amproc'::pg_catalog.regclass "
                              13704                 :                :                       "AND objid = ap.oid "
                              13705                 :                :                       "ORDER BY amprocnum",
                              13706                 :            253 :                       opfinfo->dobj.catId.oid);
                              13707                 :                : 
 4450 rhaas@postgresql.org    13708                 :            253 :     res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              13709                 :                : 
                              13710                 :                :     /* Get additional fields from the pg_opfamily row */
 6291 tgl@sss.pgh.pa.us       13711                 :            253 :     resetPQExpBuffer(query);
                              13712                 :                : 
                              13713                 :            253 :     appendPQExpBuffer(query, "SELECT "
                              13714                 :                :                       "(SELECT amname FROM pg_catalog.pg_am WHERE oid = opfmethod) AS amname "
                              13715                 :                :                       "FROM pg_catalog.pg_opfamily "
                              13716                 :                :                       "WHERE oid = '%u'::pg_catalog.oid",
                              13717                 :            253 :                       opfinfo->dobj.catId.oid);
                              13718                 :                : 
 4441 rhaas@postgresql.org    13719                 :            253 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13720                 :                : 
 6291 tgl@sss.pgh.pa.us       13721                 :            253 :     i_amname = PQfnumber(res, "amname");
                              13722                 :                : 
                              13723                 :                :     /* amname will still be needed after we PQclear res */
 4524 bruce@momjian.us        13724                 :            253 :     amname = pg_strdup(PQgetvalue(res, 0, i_amname));
                              13725                 :                : 
 6291 tgl@sss.pgh.pa.us       13726                 :            253 :     appendPQExpBuffer(delq, "DROP OPERATOR FAMILY %s",
 2239                         13727                 :            253 :                       fmtQualifiedDumpable(opfinfo));
 6291                         13728                 :            253 :     appendPQExpBuffer(delq, " USING %s;\n",
                              13729                 :                :                       fmtId(amname));
                              13730                 :                : 
                              13731                 :                :     /* Build the fixed portion of the CREATE command */
                              13732                 :            253 :     appendPQExpBuffer(q, "CREATE OPERATOR FAMILY %s",
 2239                         13733                 :            253 :                       fmtQualifiedDumpable(opfinfo));
 6291                         13734                 :            253 :     appendPQExpBuffer(q, " USING %s;\n",
                              13735                 :                :                       fmtId(amname));
                              13736                 :                : 
                              13737                 :            253 :     PQclear(res);
                              13738                 :                : 
                              13739                 :                :     /* Do we need an ALTER to add loose members? */
                              13740   [ +  +  +  + ]:            253 :     if (PQntuples(res_ops) > 0 || PQntuples(res_procs) > 0)
                              13741                 :                :     {
                              13742                 :             51 :         appendPQExpBuffer(q, "ALTER OPERATOR FAMILY %s",
 2239                         13743                 :             51 :                           fmtQualifiedDumpable(opfinfo));
 6291                         13744                 :             51 :         appendPQExpBuffer(q, " USING %s ADD\n    ",
                              13745                 :                :                           fmtId(amname));
                              13746                 :                : 
                              13747                 :             51 :         needComma = false;
                              13748                 :                : 
                              13749                 :                :         /*
                              13750                 :                :          * Now fetch and print the OPERATOR entries (pg_amop rows).
                              13751                 :                :          */
                              13752                 :             51 :         ntups = PQntuples(res_ops);
                              13753                 :                : 
                              13754                 :             51 :         i_amopstrategy = PQfnumber(res_ops, "amopstrategy");
                              13755                 :             51 :         i_amopopr = PQfnumber(res_ops, "amopopr");
 4890                         13756                 :             51 :         i_sortfamily = PQfnumber(res_ops, "sortfamily");
                              13757                 :             51 :         i_sortfamilynsp = PQfnumber(res_ops, "sortfamilynsp");
                              13758                 :                : 
 6291                         13759         [ +  + ]:            231 :         for (i = 0; i < ntups; i++)
                              13760                 :                :         {
                              13761                 :            180 :             amopstrategy = PQgetvalue(res_ops, i, i_amopstrategy);
                              13762                 :            180 :             amopopr = PQgetvalue(res_ops, i, i_amopopr);
 4890                         13763                 :            180 :             sortfamily = PQgetvalue(res_ops, i, i_sortfamily);
                              13764                 :            180 :             sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
                              13765                 :                : 
 6291                         13766         [ +  + ]:            180 :             if (needComma)
 3800 heikki.linnakangas@i    13767                 :            144 :                 appendPQExpBufferStr(q, " ,\n    ");
                              13768                 :                : 
 6291 tgl@sss.pgh.pa.us       13769                 :            180 :             appendPQExpBuffer(q, "OPERATOR %s %s",
                              13770                 :                :                               amopstrategy, amopopr);
                              13771                 :                : 
 4890                         13772         [ -  + ]:            180 :             if (strlen(sortfamily) > 0)
                              13773                 :                :             {
 3800 heikki.linnakangas@i    13774                 :UBC           0 :                 appendPQExpBufferStr(q, " FOR ORDER BY ");
 2239 tgl@sss.pgh.pa.us       13775                 :              0 :                 appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
 3800 heikki.linnakangas@i    13776                 :              0 :                 appendPQExpBufferStr(q, fmtId(sortfamily));
                              13777                 :                :             }
                              13778                 :                : 
 6291 tgl@sss.pgh.pa.us       13779                 :CBC         180 :             needComma = true;
                              13780                 :                :         }
                              13781                 :                : 
                              13782                 :                :         /*
                              13783                 :                :          * Now fetch and print the FUNCTION entries (pg_amproc rows).
                              13784                 :                :          */
                              13785                 :             51 :         ntups = PQntuples(res_procs);
                              13786                 :                : 
                              13787                 :             51 :         i_amprocnum = PQfnumber(res_procs, "amprocnum");
                              13788                 :             51 :         i_amproc = PQfnumber(res_procs, "amproc");
                              13789                 :             51 :         i_amproclefttype = PQfnumber(res_procs, "amproclefttype");
                              13790                 :             51 :         i_amprocrighttype = PQfnumber(res_procs, "amprocrighttype");
                              13791                 :                : 
                              13792         [ +  + ]:            246 :         for (i = 0; i < ntups; i++)
                              13793                 :                :         {
                              13794                 :            195 :             amprocnum = PQgetvalue(res_procs, i, i_amprocnum);
                              13795                 :            195 :             amproc = PQgetvalue(res_procs, i, i_amproc);
                              13796                 :            195 :             amproclefttype = PQgetvalue(res_procs, i, i_amproclefttype);
                              13797                 :            195 :             amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
                              13798                 :                : 
                              13799         [ +  + ]:            195 :             if (needComma)
 3800 heikki.linnakangas@i    13800                 :            180 :                 appendPQExpBufferStr(q, " ,\n    ");
                              13801                 :                : 
 6291 tgl@sss.pgh.pa.us       13802                 :            195 :             appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
                              13803                 :                :                               amprocnum, amproclefttype, amprocrighttype,
                              13804                 :                :                               amproc);
                              13805                 :                : 
                              13806                 :            195 :             needComma = true;
                              13807                 :                :         }
                              13808                 :                : 
 3800 heikki.linnakangas@i    13809                 :             51 :         appendPQExpBufferStr(q, ";\n");
                              13810                 :                :     }
                              13811                 :                : 
 2239 tgl@sss.pgh.pa.us       13812                 :            253 :     appendPQExpBufferStr(nameusing, fmtId(opfinfo->dobj.name));
                              13813                 :            253 :     appendPQExpBuffer(nameusing, " USING %s",
                              13814                 :                :                       fmtId(amname));
                              13815                 :                : 
 3470 alvherre@alvh.no-ip.    13816         [ +  + ]:            253 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       13817                 :              9 :         binary_upgrade_extension_member(q, &opfinfo->dobj,
                              13818                 :              9 :                                         "OPERATOR FAMILY", nameusing->data,
                              13819                 :              9 :                                         opfinfo->dobj.namespace->dobj.name);
                              13820                 :                : 
 2930 sfrost@snowman.net      13821         [ +  - ]:            253 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              13822                 :            253 :         ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    13823                 :            253 :                      ARCHIVE_OPTS(.tag = opfinfo->dobj.name,
                              13824                 :                :                                   .namespace = opfinfo->dobj.namespace->dobj.name,
                              13825                 :                :                                   .owner = opfinfo->rolname,
                              13826                 :                :                                   .description = "OPERATOR FAMILY",
                              13827                 :                :                                   .section = SECTION_PRE_DATA,
                              13828                 :                :                                   .createStmt = q->data,
                              13829                 :                :                                   .dropStmt = delq->data));
                              13830                 :                : 
                              13831                 :                :     /* Dump Operator Family Comments */
 2930 sfrost@snowman.net      13832         [ -  + ]:            253 :     if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       13833                 :UBC           0 :         dumpComment(fout, "OPERATOR FAMILY", nameusing->data,
 2596                         13834                 :              0 :                     opfinfo->dobj.namespace->dobj.name, opfinfo->rolname,
 2930 sfrost@snowman.net      13835                 :              0 :                     opfinfo->dobj.catId, 0, opfinfo->dobj.dumpId);
                              13836                 :                : 
 6291 tgl@sss.pgh.pa.us       13837                 :CBC         253 :     free(amname);
                              13838                 :            253 :     PQclear(res_ops);
                              13839                 :            253 :     PQclear(res_procs);
                              13840                 :            253 :     destroyPQExpBuffer(query);
                              13841                 :            253 :     destroyPQExpBuffer(q);
                              13842                 :            253 :     destroyPQExpBuffer(delq);
 2239                         13843                 :            253 :     destroyPQExpBuffer(nameusing);
                              13844                 :                : }
                              13845                 :                : 
                              13846                 :                : /*
                              13847                 :                :  * dumpCollation
                              13848                 :                :  *    write out a single collation definition
                              13849                 :                :  */
                              13850                 :                : static void
 1159 peter@eisentraut.org    13851                 :           1547 : dumpCollation(Archive *fout, const CollInfo *collinfo)
                              13852                 :                : {
 3014 tgl@sss.pgh.pa.us       13853                 :           1547 :     DumpOptions *dopt = fout->dopt;
                              13854                 :                :     PQExpBuffer query;
                              13855                 :                :     PQExpBuffer q;
                              13856                 :                :     PQExpBuffer delq;
                              13857                 :                :     char       *qcollname;
                              13858                 :                :     PGresult   *res;
                              13859                 :                :     int         i_collprovider;
                              13860                 :                :     int         i_collisdeterministic;
                              13861                 :                :     int         i_collcollate;
                              13862                 :                :     int         i_collctype;
                              13863                 :                :     int         i_colllocale;
                              13864                 :                :     int         i_collicurules;
                              13865                 :                :     const char *collprovider;
                              13866                 :                :     const char *collcollate;
                              13867                 :                :     const char *collctype;
                              13868                 :                :     const char *colllocale;
                              13869                 :                :     const char *collicurules;
                              13870                 :                : 
                              13871                 :                :     /* Do nothing in data-only dump */
  860                         13872         [ +  + ]:           1547 :     if (dopt->dataOnly)
 4810 peter_e@gmx.net         13873                 :              6 :         return;
                              13874                 :                : 
                              13875                 :           1541 :     query = createPQExpBuffer();
                              13876                 :           1541 :     q = createPQExpBuffer();
                              13877                 :           1541 :     delq = createPQExpBuffer();
                              13878                 :                : 
 2239 tgl@sss.pgh.pa.us       13879                 :           1541 :     qcollname = pg_strdup(fmtId(collinfo->dobj.name));
                              13880                 :                : 
                              13881                 :                :     /* Get collation-specific details */
 1746 drowley@postgresql.o    13882                 :           1541 :     appendPQExpBufferStr(query, "SELECT ");
                              13883                 :                : 
 2579 peter_e@gmx.net         13884         [ +  - ]:           1541 :     if (fout->remoteVersion >= 100000)
 1746 drowley@postgresql.o    13885                 :           1541 :         appendPQExpBufferStr(query,
                              13886                 :                :                              "collprovider, "
                              13887                 :                :                              "collversion, ");
                              13888                 :                :     else
 1746 drowley@postgresql.o    13889                 :UBC           0 :         appendPQExpBufferStr(query,
                              13890                 :                :                              "'c' AS collprovider, "
                              13891                 :                :                              "NULL AS collversion, ");
                              13892                 :                : 
 1850 peter@eisentraut.org    13893         [ +  - ]:CBC        1541 :     if (fout->remoteVersion >= 120000)
 1746 drowley@postgresql.o    13894                 :           1541 :         appendPQExpBufferStr(query,
                              13895                 :                :                              "collisdeterministic, ");
                              13896                 :                :     else
 1746 drowley@postgresql.o    13897                 :UBC           0 :         appendPQExpBufferStr(query,
                              13898                 :                :                              "true AS collisdeterministic, ");
                              13899                 :                : 
   36 jdavis@postgresql.or    13900         [ +  - ]:GNC        1541 :     if (fout->remoteVersion >= 170000)
   36 jdavis@postgresql.or    13901                 :CBC        1541 :         appendPQExpBufferStr(query,
                              13902                 :                :                              "colllocale, ");
   36 jdavis@postgresql.or    13903         [ #  # ]:UNC           0 :     else if (fout->remoteVersion >= 150000)
  599 peter@eisentraut.org    13904                 :              0 :         appendPQExpBufferStr(query,
                              13905                 :                :                              "colliculocale AS colllocale, ");
                              13906                 :                :     else
  599 peter@eisentraut.org    13907                 :UBC           0 :         appendPQExpBufferStr(query,
                              13908                 :                :                              "NULL AS colllocale, ");
                              13909                 :                : 
  403 peter@eisentraut.org    13910         [ +  - ]:CBC        1541 :     if (fout->remoteVersion >= 160000)
                              13911                 :           1541 :         appendPQExpBufferStr(query,
                              13912                 :                :                              "collicurules, ");
                              13913                 :                :     else
  403 peter@eisentraut.org    13914                 :UBC           0 :         appendPQExpBufferStr(query,
                              13915                 :                :                              "NULL AS collicurules, ");
                              13916                 :                : 
 1850 peter@eisentraut.org    13917                 :CBC        1541 :     appendPQExpBuffer(query,
                              13918                 :                :                       "collcollate, "
                              13919                 :                :                       "collctype "
                              13920                 :                :                       "FROM pg_catalog.pg_collation c "
                              13921                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
                              13922                 :           1541 :                       collinfo->dobj.catId.oid);
                              13923                 :                : 
 4441 rhaas@postgresql.org    13924                 :           1541 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              13925                 :                : 
 2579 peter_e@gmx.net         13926                 :           1541 :     i_collprovider = PQfnumber(res, "collprovider");
 1850 peter@eisentraut.org    13927                 :           1541 :     i_collisdeterministic = PQfnumber(res, "collisdeterministic");
 4810 peter_e@gmx.net         13928                 :           1541 :     i_collcollate = PQfnumber(res, "collcollate");
                              13929                 :           1541 :     i_collctype = PQfnumber(res, "collctype");
   36 jdavis@postgresql.or    13930                 :GNC        1541 :     i_colllocale = PQfnumber(res, "colllocale");
  403 peter@eisentraut.org    13931                 :CBC        1541 :     i_collicurules = PQfnumber(res, "collicurules");
                              13932                 :                : 
 2579 peter_e@gmx.net         13933                 :           1541 :     collprovider = PQgetvalue(res, 0, i_collprovider);
                              13934                 :                : 
  599 peter@eisentraut.org    13935         [ +  + ]:           1541 :     if (!PQgetisnull(res, 0, i_collcollate))
                              13936                 :            686 :         collcollate = PQgetvalue(res, 0, i_collcollate);
                              13937                 :                :     else
                              13938                 :            855 :         collcollate = NULL;
                              13939                 :                : 
                              13940         [ +  + ]:           1541 :     if (!PQgetisnull(res, 0, i_collctype))
                              13941                 :            686 :         collctype = PQgetvalue(res, 0, i_collctype);
                              13942                 :                :     else
                              13943                 :            855 :         collctype = NULL;
                              13944                 :                : 
                              13945                 :                :     /*
                              13946                 :                :      * Before version 15, collcollate and collctype were of type NAME and
                              13947                 :                :      * non-nullable. Treat empty strings as NULL for consistency.
                              13948                 :                :      */
  236 jdavis@postgresql.or    13949         [ -  + ]:           1541 :     if (fout->remoteVersion < 150000)
                              13950                 :                :     {
  236 jdavis@postgresql.or    13951         [ #  # ]:UBC           0 :         if (collcollate[0] == '\0')
                              13952                 :              0 :             collcollate = NULL;
                              13953         [ #  # ]:              0 :         if (collctype[0] == '\0')
                              13954                 :              0 :             collctype = NULL;
                              13955                 :                :     }
                              13956                 :                : 
   36 jdavis@postgresql.or    13957         [ +  + ]:GNC        1541 :     if (!PQgetisnull(res, 0, i_colllocale))
                              13958                 :            854 :         colllocale = PQgetvalue(res, 0, i_colllocale);
                              13959                 :                :     else
                              13960                 :            687 :         colllocale = NULL;
                              13961                 :                : 
  403 peter@eisentraut.org    13962         [ -  + ]:CBC        1541 :     if (!PQgetisnull(res, 0, i_collicurules))
  403 peter@eisentraut.org    13963                 :UBC           0 :         collicurules = PQgetvalue(res, 0, i_collicurules);
                              13964                 :                :     else
  403 peter@eisentraut.org    13965                 :CBC        1541 :         collicurules = NULL;
                              13966                 :                : 
 2239 tgl@sss.pgh.pa.us       13967                 :           1541 :     appendPQExpBuffer(delq, "DROP COLLATION %s;\n",
                              13968                 :           1541 :                       fmtQualifiedDumpable(collinfo));
                              13969                 :                : 
 2579 peter_e@gmx.net         13970                 :           1541 :     appendPQExpBuffer(q, "CREATE COLLATION %s (",
 2239 tgl@sss.pgh.pa.us       13971                 :           1541 :                       fmtQualifiedDumpable(collinfo));
                              13972                 :                : 
 2579 peter_e@gmx.net         13973                 :           1541 :     appendPQExpBufferStr(q, "provider = ");
   32 jdavis@postgresql.or    13974         [ +  + ]:GNC        1541 :     if (collprovider[0] == 'b')
                              13975                 :              7 :         appendPQExpBufferStr(q, "builtin");
                              13976         [ +  + ]:           1534 :     else if (collprovider[0] == 'c')
 2579 peter_e@gmx.net         13977                 :CBC         686 :         appendPQExpBufferStr(q, "libc");
                              13978         [ +  + ]:            848 :     else if (collprovider[0] == 'i')
                              13979                 :            847 :         appendPQExpBufferStr(q, "icu");
 2497                         13980         [ +  - ]:              1 :     else if (collprovider[0] == 'd')
                              13981                 :                :         /* to allow dumping pg_catalog; not accepted on input */
                              13982                 :              1 :         appendPQExpBufferStr(q, "default");
                              13983                 :                :     else
  737 tgl@sss.pgh.pa.us       13984                 :UBC           0 :         pg_fatal("unrecognized collation provider: %s",
                              13985                 :                :                  collprovider);
                              13986                 :                : 
 1850 peter@eisentraut.org    13987         [ -  + ]:CBC        1541 :     if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0)
 1850 peter@eisentraut.org    13988                 :UBC           0 :         appendPQExpBufferStr(q, ", deterministic = false");
                              13989                 :                : 
  236 jdavis@postgresql.or    13990         [ +  + ]:CBC        1541 :     if (collprovider[0] == 'd')
                              13991                 :                :     {
   36 jdavis@postgresql.or    13992   [ +  -  +  -  :GNC           1 :         if (collcollate || collctype || colllocale || collicurules)
                                        +  -  -  + ]
  236 jdavis@postgresql.or    13993                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              13994                 :                : 
                              13995                 :                :         /* no locale -- the default collation cannot be reloaded anyway */
                              13996                 :                :     }
   32 jdavis@postgresql.or    13997         [ +  + ]:GNC        1540 :     else if (collprovider[0] == 'b')
                              13998                 :                :     {
                              13999   [ +  -  +  -  :              7 :         if (collcollate || collctype || !colllocale || collicurules)
                                        +  -  -  + ]
   32 jdavis@postgresql.or    14000                 :UNC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              14001                 :                : 
   32 jdavis@postgresql.or    14002                 :GNC           7 :         appendPQExpBufferStr(q, ", locale = ");
                              14003         [ +  - ]:              7 :         appendStringLiteralAH(q, colllocale ? colllocale : "",
                              14004                 :                :                               fout);
                              14005                 :                :     }
  236 jdavis@postgresql.or    14006         [ +  + ]:CBC        1533 :     else if (collprovider[0] == 'i')
                              14007                 :                :     {
                              14008         [ +  - ]:            847 :         if (fout->remoteVersion >= 150000)
                              14009                 :                :         {
   36 jdavis@postgresql.or    14010   [ +  -  +  -  :GNC         847 :             if (collcollate || collctype || !colllocale)
                                              -  + ]
  236 jdavis@postgresql.or    14011                 :UBC           0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              14012                 :                : 
  236 jdavis@postgresql.or    14013                 :CBC         847 :             appendPQExpBufferStr(q, ", locale = ");
   36 jdavis@postgresql.or    14014         [ +  - ]:GNC         847 :             appendStringLiteralAH(q, colllocale ? colllocale : "",
                              14015                 :                :                                   fout);
                              14016                 :                :         }
                              14017                 :                :         else
                              14018                 :                :         {
   36 jdavis@postgresql.or    14019   [ #  #  #  #  :UNC           0 :             if (!collcollate || !collctype || colllocale ||
                                              #  # ]
  236 jdavis@postgresql.or    14020         [ #  # ]:UBC           0 :                 strcmp(collcollate, collctype) != 0)
                              14021                 :              0 :                 pg_log_warning("invalid collation \"%s\"", qcollname);
                              14022                 :                : 
  599 peter@eisentraut.org    14023                 :              0 :             appendPQExpBufferStr(q, ", locale = ");
  236 jdavis@postgresql.or    14024         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              14025                 :                :         }
                              14026                 :                : 
  236 jdavis@postgresql.or    14027         [ -  + ]:CBC         847 :         if (collicurules)
                              14028                 :                :         {
  236 jdavis@postgresql.or    14029                 :UBC           0 :             appendPQExpBufferStr(q, ", rules = ");
                              14030         [ #  # ]:              0 :             appendStringLiteralAH(q, collicurules ? collicurules : "", fout);
                              14031                 :                :         }
                              14032                 :                :     }
  236 jdavis@postgresql.or    14033         [ +  - ]:CBC         686 :     else if (collprovider[0] == 'c')
                              14034                 :                :     {
   36 jdavis@postgresql.or    14035   [ +  -  +  -  :GNC         686 :         if (colllocale || collicurules || !collcollate || !collctype)
                                        +  -  -  + ]
  236 jdavis@postgresql.or    14036                 :UBC           0 :             pg_log_warning("invalid collation \"%s\"", qcollname);
                              14037                 :                : 
  236 jdavis@postgresql.or    14038   [ +  -  +  -  :CBC         686 :         if (collcollate && collctype && strcmp(collcollate, collctype) == 0)
                                              +  - ]
                              14039                 :                :         {
                              14040                 :            686 :             appendPQExpBufferStr(q, ", locale = ");
                              14041         [ +  - ]:            686 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
                              14042                 :                :         }
                              14043                 :                :         else
                              14044                 :                :         {
  599 peter@eisentraut.org    14045                 :UBC           0 :             appendPQExpBufferStr(q, ", lc_collate = ");
  236 jdavis@postgresql.or    14046         [ #  # ]:              0 :             appendStringLiteralAH(q, collcollate ? collcollate : "", fout);
  599 peter@eisentraut.org    14047                 :              0 :             appendPQExpBufferStr(q, ", lc_ctype = ");
  236 jdavis@postgresql.or    14048         [ #  # ]:              0 :             appendStringLiteralAH(q, collctype ? collctype : "", fout);
                              14049                 :                :         }
                              14050                 :                :     }
                              14051                 :                :     else
  222 peter@eisentraut.org    14052                 :              0 :         pg_fatal("unrecognized collation provider: %s", collprovider);
                              14053                 :                : 
                              14054                 :                :     /*
                              14055                 :                :      * For binary upgrade, carry over the collation version.  For normal
                              14056                 :                :      * dump/restore, omit the version, so that it is computed upon restore.
                              14057                 :                :      */
 1073 tmunro@postgresql.or    14058         [ +  + ]:CBC        1541 :     if (dopt->binary_upgrade)
                              14059                 :                :     {
                              14060                 :                :         int         i_collversion;
                              14061                 :                : 
                              14062                 :              4 :         i_collversion = PQfnumber(res, "collversion");
                              14063         [ +  + ]:              4 :         if (!PQgetisnull(res, 0, i_collversion))
                              14064                 :                :         {
                              14065                 :              3 :             appendPQExpBufferStr(q, ", version = ");
                              14066                 :              3 :             appendStringLiteralAH(q,
                              14067                 :                :                                   PQgetvalue(res, 0, i_collversion),
                              14068                 :                :                                   fout);
                              14069                 :                :         }
                              14070                 :                :     }
                              14071                 :                : 
 3800 heikki.linnakangas@i    14072                 :           1541 :     appendPQExpBufferStr(q, ");\n");
                              14073                 :                : 
 3470 alvherre@alvh.no-ip.    14074         [ +  + ]:           1541 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14075                 :              4 :         binary_upgrade_extension_member(q, &collinfo->dobj,
                              14076                 :                :                                         "COLLATION", qcollname,
                              14077                 :              4 :                                         collinfo->dobj.namespace->dobj.name);
                              14078                 :                : 
 2930 sfrost@snowman.net      14079         [ +  - ]:           1541 :     if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14080                 :           1541 :         ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14081                 :           1541 :                      ARCHIVE_OPTS(.tag = collinfo->dobj.name,
                              14082                 :                :                                   .namespace = collinfo->dobj.namespace->dobj.name,
                              14083                 :                :                                   .owner = collinfo->rolname,
                              14084                 :                :                                   .description = "COLLATION",
                              14085                 :                :                                   .section = SECTION_PRE_DATA,
                              14086                 :                :                                   .createStmt = q->data,
                              14087                 :                :                                   .dropStmt = delq->data));
                              14088                 :                : 
                              14089                 :                :     /* Dump Collation Comments */
 2930 sfrost@snowman.net      14090         [ +  + ]:           1541 :     if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14091                 :            834 :         dumpComment(fout, "COLLATION", qcollname,
 2930 sfrost@snowman.net      14092                 :            834 :                     collinfo->dobj.namespace->dobj.name, collinfo->rolname,
                              14093                 :            834 :                     collinfo->dobj.catId, 0, collinfo->dobj.dumpId);
                              14094                 :                : 
 4810 peter_e@gmx.net         14095                 :           1541 :     PQclear(res);
                              14096                 :                : 
                              14097                 :           1541 :     destroyPQExpBuffer(query);
                              14098                 :           1541 :     destroyPQExpBuffer(q);
                              14099                 :           1541 :     destroyPQExpBuffer(delq);
 2239 tgl@sss.pgh.pa.us       14100                 :           1541 :     free(qcollname);
                              14101                 :                : }
                              14102                 :                : 
                              14103                 :                : /*
                              14104                 :                :  * dumpConversion
                              14105                 :                :  *    write out a single conversion definition
                              14106                 :                :  */
                              14107                 :                : static void
 1159 peter@eisentraut.org    14108                 :            167 : dumpConversion(Archive *fout, const ConvInfo *convinfo)
                              14109                 :                : {
 3014 tgl@sss.pgh.pa.us       14110                 :            167 :     DumpOptions *dopt = fout->dopt;
                              14111                 :                :     PQExpBuffer query;
                              14112                 :                :     PQExpBuffer q;
                              14113                 :                :     PQExpBuffer delq;
                              14114                 :                :     char       *qconvname;
                              14115                 :                :     PGresult   *res;
                              14116                 :                :     int         i_conforencoding;
                              14117                 :                :     int         i_contoencoding;
                              14118                 :                :     int         i_conproc;
                              14119                 :                :     int         i_condefault;
                              14120                 :                :     const char *conforencoding;
                              14121                 :                :     const char *contoencoding;
                              14122                 :                :     const char *conproc;
                              14123                 :                :     bool        condefault;
                              14124                 :                : 
                              14125                 :                :     /* Do nothing in data-only dump */
  860                         14126         [ +  + ]:            167 :     if (dopt->dataOnly)
 7435                         14127                 :              3 :         return;
                              14128                 :                : 
                              14129                 :            164 :     query = createPQExpBuffer();
                              14130                 :            164 :     q = createPQExpBuffer();
                              14131                 :            164 :     delq = createPQExpBuffer();
                              14132                 :                : 
 2239                         14133                 :            164 :     qconvname = pg_strdup(fmtId(convinfo->dobj.name));
                              14134                 :                : 
                              14135                 :                :     /* Get conversion-specific details */
 4752 peter_e@gmx.net         14136                 :            164 :     appendPQExpBuffer(query, "SELECT "
                              14137                 :                :                       "pg_catalog.pg_encoding_to_char(conforencoding) AS conforencoding, "
                              14138                 :                :                       "pg_catalog.pg_encoding_to_char(contoencoding) AS contoencoding, "
                              14139                 :                :                       "conproc, condefault "
                              14140                 :                :                       "FROM pg_catalog.pg_conversion c "
                              14141                 :                :                       "WHERE c.oid = '%u'::pg_catalog.oid",
 7435 tgl@sss.pgh.pa.us       14142                 :            164 :                       convinfo->dobj.catId.oid);
                              14143                 :                : 
 4441 rhaas@postgresql.org    14144                 :            164 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14145                 :                : 
 7450 tgl@sss.pgh.pa.us       14146                 :            164 :     i_conforencoding = PQfnumber(res, "conforencoding");
                              14147                 :            164 :     i_contoencoding = PQfnumber(res, "contoencoding");
                              14148                 :            164 :     i_conproc = PQfnumber(res, "conproc");
                              14149                 :            164 :     i_condefault = PQfnumber(res, "condefault");
                              14150                 :                : 
                              14151                 :            164 :     conforencoding = PQgetvalue(res, 0, i_conforencoding);
                              14152                 :            164 :     contoencoding = PQgetvalue(res, 0, i_contoencoding);
                              14153                 :            164 :     conproc = PQgetvalue(res, 0, i_conproc);
                              14154                 :            164 :     condefault = (PQgetvalue(res, 0, i_condefault)[0] == 't');
                              14155                 :                : 
 2239                         14156                 :            164 :     appendPQExpBuffer(delq, "DROP CONVERSION %s;\n",
                              14157                 :            164 :                       fmtQualifiedDumpable(convinfo));
                              14158                 :                : 
 7450                         14159         [ +  - ]:            164 :     appendPQExpBuffer(q, "CREATE %sCONVERSION %s FOR ",
                              14160                 :                :                       (condefault) ? "DEFAULT " : "",
 2239                         14161                 :            164 :                       fmtQualifiedDumpable(convinfo));
 6531                         14162                 :            164 :     appendStringLiteralAH(q, conforencoding, fout);
 3800 heikki.linnakangas@i    14163                 :            164 :     appendPQExpBufferStr(q, " TO ");
 6531 tgl@sss.pgh.pa.us       14164                 :            164 :     appendStringLiteralAH(q, contoencoding, fout);
                              14165                 :                :     /* regproc output is already sufficiently quoted */
 7450                         14166                 :            164 :     appendPQExpBuffer(q, " FROM %s;\n", conproc);
                              14167                 :                : 
 3470 alvherre@alvh.no-ip.    14168         [ +  + ]:            164 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14169                 :              1 :         binary_upgrade_extension_member(q, &convinfo->dobj,
                              14170                 :                :                                         "CONVERSION", qconvname,
                              14171                 :              1 :                                         convinfo->dobj.namespace->dobj.name);
                              14172                 :                : 
 2930 sfrost@snowman.net      14173         [ +  - ]:            164 :     if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14174                 :            164 :         ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14175                 :            164 :                      ARCHIVE_OPTS(.tag = convinfo->dobj.name,
                              14176                 :                :                                   .namespace = convinfo->dobj.namespace->dobj.name,
                              14177                 :                :                                   .owner = convinfo->rolname,
                              14178                 :                :                                   .description = "CONVERSION",
                              14179                 :                :                                   .section = SECTION_PRE_DATA,
                              14180                 :                :                                   .createStmt = q->data,
                              14181                 :                :                                   .dropStmt = delq->data));
                              14182                 :                : 
                              14183                 :                :     /* Dump Conversion Comments */
 2930 sfrost@snowman.net      14184         [ +  - ]:            164 :     if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14185                 :            164 :         dumpComment(fout, "CONVERSION", qconvname,
 2930 sfrost@snowman.net      14186                 :            164 :                     convinfo->dobj.namespace->dobj.name, convinfo->rolname,
                              14187                 :            164 :                     convinfo->dobj.catId, 0, convinfo->dobj.dumpId);
                              14188                 :                : 
 7435 tgl@sss.pgh.pa.us       14189                 :            164 :     PQclear(res);
                              14190                 :                : 
                              14191                 :            164 :     destroyPQExpBuffer(query);
                              14192                 :            164 :     destroyPQExpBuffer(q);
                              14193                 :            164 :     destroyPQExpBuffer(delq);
 2239                         14194                 :            164 :     free(qconvname);
                              14195                 :                : }
                              14196                 :                : 
                              14197                 :                : /*
                              14198                 :                :  * format_aggregate_signature: generate aggregate name and argument list
                              14199                 :                :  *
                              14200                 :                :  * The argument type names are qualified if needed.  The aggregate name
                              14201                 :                :  * is never qualified.
                              14202                 :                :  */
                              14203                 :                : static char *
 1159 peter@eisentraut.org    14204                 :            289 : format_aggregate_signature(const AggInfo *agginfo, Archive *fout, bool honor_quotes)
                              14205                 :                : {
                              14206                 :                :     PQExpBufferData buf;
                              14207                 :                :     int         j;
                              14208                 :                : 
 8001 peter_e@gmx.net         14209                 :            289 :     initPQExpBuffer(&buf);
 7955 bruce@momjian.us        14210         [ -  + ]:            289 :     if (honor_quotes)
 3800 heikki.linnakangas@i    14211                 :UBC           0 :         appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
                              14212                 :                :     else
 3800 heikki.linnakangas@i    14213                 :CBC         289 :         appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
                              14214                 :                : 
 6471 tgl@sss.pgh.pa.us       14215         [ +  + ]:            289 :     if (agginfo->aggfn.nargs == 0)
 1746 drowley@postgresql.o    14216                 :             40 :         appendPQExpBufferStr(&buf, "(*)");
                              14217                 :                :     else
                              14218                 :                :     {
 3800 heikki.linnakangas@i    14219                 :            249 :         appendPQExpBufferChar(&buf, '(');
 6471 tgl@sss.pgh.pa.us       14220         [ +  + ]:            543 :         for (j = 0; j < agginfo->aggfn.nargs; j++)
                              14221         [ +  + ]:            294 :             appendPQExpBuffer(&buf, "%s%s",
                              14222                 :                :                               (j > 0) ? ", " : "",
                              14223                 :                :                               getFormattedTypeName(fout,
  949                         14224                 :            294 :                                                    agginfo->aggfn.argtypes[j],
                              14225                 :                :                                                    zeroIsError));
 3800 heikki.linnakangas@i    14226                 :            249 :         appendPQExpBufferChar(&buf, ')');
                              14227                 :                :     }
 8001 peter_e@gmx.net         14228                 :            289 :     return buf.data;
                              14229                 :                : }
                              14230                 :                : 
                              14231                 :                : /*
                              14232                 :                :  * dumpAgg
                              14233                 :                :  *    write out a single aggregate definition
                              14234                 :                :  */
                              14235                 :                : static void
 1159 peter@eisentraut.org    14236                 :            293 : dumpAgg(Archive *fout, const AggInfo *agginfo)
                              14237                 :                : {
 3014 tgl@sss.pgh.pa.us       14238                 :            293 :     DumpOptions *dopt = fout->dopt;
                              14239                 :                :     PQExpBuffer query;
                              14240                 :                :     PQExpBuffer q;
                              14241                 :                :     PQExpBuffer delq;
                              14242                 :                :     PQExpBuffer details;
                              14243                 :                :     char       *aggsig;         /* identity signature */
 2489                         14244                 :            293 :     char       *aggfullsig = NULL;  /* full signature */
                              14245                 :                :     char       *aggsig_tag;
                              14246                 :                :     PGresult   *res;
                              14247                 :                :     int         i_agginitval;
                              14248                 :                :     int         i_aggminitval;
                              14249                 :                :     const char *aggtransfn;
                              14250                 :                :     const char *aggfinalfn;
                              14251                 :                :     const char *aggcombinefn;
                              14252                 :                :     const char *aggserialfn;
                              14253                 :                :     const char *aggdeserialfn;
                              14254                 :                :     const char *aggmtransfn;
                              14255                 :                :     const char *aggminvtransfn;
                              14256                 :                :     const char *aggmfinalfn;
                              14257                 :                :     bool        aggfinalextra;
                              14258                 :                :     bool        aggmfinalextra;
                              14259                 :                :     char        aggfinalmodify;
                              14260                 :                :     char        aggmfinalmodify;
                              14261                 :                :     const char *aggsortop;
                              14262                 :                :     char       *aggsortconvop;
                              14263                 :                :     char        aggkind;
                              14264                 :                :     const char *aggtranstype;
                              14265                 :                :     const char *aggtransspace;
                              14266                 :                :     const char *aggmtranstype;
                              14267                 :                :     const char *aggmtransspace;
                              14268                 :                :     const char *agginitval;
                              14269                 :                :     const char *aggminitval;
                              14270                 :                :     const char *proparallel;
                              14271                 :                :     char        defaultfinalmodify;
                              14272                 :                : 
                              14273                 :                :     /* Do nothing in data-only dump */
  860                         14274         [ +  + ]:            293 :     if (dopt->dataOnly)
 7435                         14275                 :              4 :         return;
                              14276                 :                : 
                              14277                 :            289 :     query = createPQExpBuffer();
                              14278                 :            289 :     q = createPQExpBuffer();
                              14279                 :            289 :     delq = createPQExpBuffer();
                              14280                 :            289 :     details = createPQExpBuffer();
                              14281                 :                : 
  860                         14282         [ +  + ]:            289 :     if (!fout->is_prepared[PREPQUERY_DUMPAGG])
                              14283                 :                :     {
                              14284                 :                :         /* Set up query for aggregate-specific details */
 1277 drowley@postgresql.o    14285                 :             59 :         appendPQExpBufferStr(query,
                              14286                 :                :                              "PREPARE dumpAgg(pg_catalog.oid) AS\n");
                              14287                 :                : 
                              14288                 :             59 :         appendPQExpBufferStr(query,
                              14289                 :                :                              "SELECT "
                              14290                 :                :                              "aggtransfn,\n"
                              14291                 :                :                              "aggfinalfn,\n"
                              14292                 :                :                              "aggtranstype::pg_catalog.regtype,\n"
                              14293                 :                :                              "agginitval,\n"
                              14294                 :                :                              "aggsortop,\n"
                              14295                 :                :                              "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs,\n"
                              14296                 :                :                              "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs,\n");
                              14297                 :                : 
  860 tgl@sss.pgh.pa.us       14298         [ +  - ]:             59 :         if (fout->remoteVersion >= 90400)
                              14299                 :             59 :             appendPQExpBufferStr(query,
                              14300                 :                :                                  "aggkind,\n"
                              14301                 :                :                                  "aggmtransfn,\n"
                              14302                 :                :                                  "aggminvtransfn,\n"
                              14303                 :                :                                  "aggmfinalfn,\n"
                              14304                 :                :                                  "aggmtranstype::pg_catalog.regtype,\n"
                              14305                 :                :                                  "aggfinalextra,\n"
                              14306                 :                :                                  "aggmfinalextra,\n"
                              14307                 :                :                                  "aggtransspace,\n"
                              14308                 :                :                                  "aggmtransspace,\n"
                              14309                 :                :                                  "aggminitval,\n");
                              14310                 :                :         else
  860 tgl@sss.pgh.pa.us       14311                 :UBC           0 :             appendPQExpBufferStr(query,
                              14312                 :                :                                  "'n' AS aggkind,\n"
                              14313                 :                :                                  "'-' AS aggmtransfn,\n"
                              14314                 :                :                                  "'-' AS aggminvtransfn,\n"
                              14315                 :                :                                  "'-' AS aggmfinalfn,\n"
                              14316                 :                :                                  "0 AS aggmtranstype,\n"
                              14317                 :                :                                  "false AS aggfinalextra,\n"
                              14318                 :                :                                  "false AS aggmfinalextra,\n"
                              14319                 :                :                                  "0 AS aggtransspace,\n"
                              14320                 :                :                                  "0 AS aggmtransspace,\n"
                              14321                 :                :                                  "NULL AS aggminitval,\n");
                              14322                 :                : 
  860 tgl@sss.pgh.pa.us       14323         [ +  - ]:CBC          59 :         if (fout->remoteVersion >= 90600)
                              14324                 :             59 :             appendPQExpBufferStr(query,
                              14325                 :                :                                  "aggcombinefn,\n"
                              14326                 :                :                                  "aggserialfn,\n"
                              14327                 :                :                                  "aggdeserialfn,\n"
                              14328                 :                :                                  "proparallel,\n");
                              14329                 :                :         else
  860 tgl@sss.pgh.pa.us       14330                 :UBC           0 :             appendPQExpBufferStr(query,
                              14331                 :                :                                  "'-' AS aggcombinefn,\n"
                              14332                 :                :                                  "'-' AS aggserialfn,\n"
                              14333                 :                :                                  "'-' AS aggdeserialfn,\n"
                              14334                 :                :                                  "'u' AS proparallel,\n");
                              14335                 :                : 
  860 tgl@sss.pgh.pa.us       14336         [ +  - ]:CBC          59 :         if (fout->remoteVersion >= 110000)
                              14337                 :             59 :             appendPQExpBufferStr(query,
                              14338                 :                :                                  "aggfinalmodify,\n"
                              14339                 :                :                                  "aggmfinalmodify\n");
                              14340                 :                :         else
  860 tgl@sss.pgh.pa.us       14341                 :UBC           0 :             appendPQExpBufferStr(query,
                              14342                 :                :                                  "'0' AS aggfinalmodify,\n"
                              14343                 :                :                                  "'0' AS aggmfinalmodify\n");
                              14344                 :                : 
 1277 drowley@postgresql.o    14345                 :CBC          59 :         appendPQExpBufferStr(query,
                              14346                 :                :                              "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                              14347                 :                :                              "WHERE a.aggfnoid = p.oid "
                              14348                 :                :                              "AND p.oid = $1");
                              14349                 :                : 
  860 tgl@sss.pgh.pa.us       14350                 :             59 :         ExecuteSqlStatement(fout, query->data);
                              14351                 :                : 
                              14352                 :             59 :         fout->is_prepared[PREPQUERY_DUMPAGG] = true;
                              14353                 :                :     }
                              14354                 :                : 
                              14355                 :            289 :     printfPQExpBuffer(query,
                              14356                 :                :                       "EXECUTE dumpAgg('%u')",
 1369 peter@eisentraut.org    14357                 :            289 :                       agginfo->aggfn.dobj.catId.oid);
                              14358                 :                : 
 4441 rhaas@postgresql.org    14359                 :            289 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              14360                 :                : 
 8010 tgl@sss.pgh.pa.us       14361                 :            289 :     i_agginitval = PQfnumber(res, "agginitval");
 3655                         14362                 :            289 :     i_aggminitval = PQfnumber(res, "aggminitval");
                              14363                 :                : 
 1369 peter@eisentraut.org    14364                 :            289 :     aggtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggtransfn"));
                              14365                 :            289 :     aggfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggfinalfn"));
                              14366                 :            289 :     aggcombinefn = PQgetvalue(res, 0, PQfnumber(res, "aggcombinefn"));
                              14367                 :            289 :     aggserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggserialfn"));
                              14368                 :            289 :     aggdeserialfn = PQgetvalue(res, 0, PQfnumber(res, "aggdeserialfn"));
                              14369                 :            289 :     aggmtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggmtransfn"));
                              14370                 :            289 :     aggminvtransfn = PQgetvalue(res, 0, PQfnumber(res, "aggminvtransfn"));
                              14371                 :            289 :     aggmfinalfn = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalfn"));
                              14372                 :            289 :     aggfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggfinalextra"))[0] == 't');
                              14373                 :            289 :     aggmfinalextra = (PQgetvalue(res, 0, PQfnumber(res, "aggmfinalextra"))[0] == 't');
                              14374                 :            289 :     aggfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggfinalmodify"))[0];
                              14375                 :            289 :     aggmfinalmodify = PQgetvalue(res, 0, PQfnumber(res, "aggmfinalmodify"))[0];
                              14376                 :            289 :     aggsortop = PQgetvalue(res, 0, PQfnumber(res, "aggsortop"));
                              14377                 :            289 :     aggkind = PQgetvalue(res, 0, PQfnumber(res, "aggkind"))[0];
                              14378                 :            289 :     aggtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggtranstype"));
                              14379                 :            289 :     aggtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggtransspace"));
                              14380                 :            289 :     aggmtranstype = PQgetvalue(res, 0, PQfnumber(res, "aggmtranstype"));
                              14381                 :            289 :     aggmtransspace = PQgetvalue(res, 0, PQfnumber(res, "aggmtransspace"));
 8010 tgl@sss.pgh.pa.us       14382                 :            289 :     agginitval = PQgetvalue(res, 0, i_agginitval);
 3655                         14383                 :            289 :     aggminitval = PQgetvalue(res, 0, i_aggminitval);
 1369 peter@eisentraut.org    14384                 :            289 :     proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel"));
                              14385                 :                : 
                              14386                 :                :     {
                              14387                 :                :         char       *funcargs;
                              14388                 :                :         char       *funciargs;
                              14389                 :                : 
 3876 tgl@sss.pgh.pa.us       14390                 :            289 :         funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                              14391                 :            289 :         funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
                              14392                 :            289 :         aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
                              14393                 :            289 :         aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
                              14394                 :                :     }
                              14395                 :                : 
 7435                         14396                 :            289 :     aggsig_tag = format_aggregate_signature(agginfo, fout, false);
                              14397                 :                : 
                              14398                 :                :     /* identify default modify flag for aggkind (must match DefineAggregate) */
 2374                         14399         [ +  + ]:            289 :     defaultfinalmodify = (aggkind == AGGKIND_NORMAL) ? AGGMODIFY_READ_ONLY : AGGMODIFY_READ_WRITE;
                              14400                 :                :     /* replace omitted flags for old versions */
                              14401         [ -  + ]:            289 :     if (aggfinalmodify == '0')
 2374 tgl@sss.pgh.pa.us       14402                 :UBC           0 :         aggfinalmodify = defaultfinalmodify;
 2374 tgl@sss.pgh.pa.us       14403         [ -  + ]:CBC         289 :     if (aggmfinalmodify == '0')
 2374 tgl@sss.pgh.pa.us       14404                 :UBC           0 :         aggmfinalmodify = defaultfinalmodify;
                              14405                 :                : 
                              14406                 :                :     /* regproc and regtype output is already sufficiently quoted */
 2741 tgl@sss.pgh.pa.us       14407                 :CBC         289 :     appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                              14408                 :                :                       aggtransfn, aggtranstype);
                              14409                 :                : 
 3802                         14410         [ +  + ]:            289 :     if (strcmp(aggtransspace, "0") != 0)
                              14411                 :                :     {
                              14412                 :              5 :         appendPQExpBuffer(details, ",\n    SSPACE = %s",
                              14413                 :                :                           aggtransspace);
                              14414                 :                :     }
                              14415                 :                : 
 8010                         14416         [ +  + ]:            289 :     if (!PQgetisnull(res, 0, i_agginitval))
                              14417                 :                :     {
 3800 heikki.linnakangas@i    14418                 :            211 :         appendPQExpBufferStr(details, ",\n    INITCOND = ");
 6531 tgl@sss.pgh.pa.us       14419                 :            211 :         appendStringLiteralAH(details, agginitval, fout);
                              14420                 :                :     }
                              14421                 :                : 
 8010                         14422         [ +  + ]:            289 :     if (strcmp(aggfinalfn, "-") != 0)
                              14423                 :                :     {
 7910 peter_e@gmx.net         14424                 :            136 :         appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                              14425                 :                :                           aggfinalfn);
 3644 tgl@sss.pgh.pa.us       14426         [ +  + ]:            136 :         if (aggfinalextra)
                              14427                 :             10 :             appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
 2374                         14428         [ +  + ]:            136 :         if (aggfinalmodify != defaultfinalmodify)
                              14429                 :                :         {
                              14430   [ -  +  -  - ]:             36 :             switch (aggfinalmodify)
                              14431                 :                :             {
 2374 tgl@sss.pgh.pa.us       14432                 :UBC           0 :                 case AGGMODIFY_READ_ONLY:
                              14433                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_ONLY");
                              14434                 :              0 :                     break;
 2155 tgl@sss.pgh.pa.us       14435                 :CBC          36 :                 case AGGMODIFY_SHAREABLE:
                              14436                 :             36 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = SHAREABLE");
 2374                         14437                 :             36 :                     break;
 2374 tgl@sss.pgh.pa.us       14438                 :UBC           0 :                 case AGGMODIFY_READ_WRITE:
                              14439                 :              0 :                     appendPQExpBufferStr(details, ",\n    FINALFUNC_MODIFY = READ_WRITE");
                              14440                 :              0 :                     break;
                              14441                 :              0 :                 default:
  737                         14442                 :              0 :                     pg_fatal("unrecognized aggfinalmodify value for aggregate \"%s\"",
                              14443                 :                :                              agginfo->aggfn.dobj.name);
                              14444                 :                :                     break;
                              14445                 :                :             }
                              14446                 :                :         }
                              14447                 :                :     }
                              14448                 :                : 
 3007 rhaas@postgresql.org    14449         [ -  + ]:CBC         289 :     if (strcmp(aggcombinefn, "-") != 0)
 2866 rhaas@postgresql.org    14450                 :UBC           0 :         appendPQExpBuffer(details, ",\n    COMBINEFUNC = %s", aggcombinefn);
                              14451                 :                : 
 2938 rhaas@postgresql.org    14452         [ -  + ]:CBC         289 :     if (strcmp(aggserialfn, "-") != 0)
 2866 rhaas@postgresql.org    14453                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SERIALFUNC = %s", aggserialfn);
                              14454                 :                : 
 2853 tgl@sss.pgh.pa.us       14455         [ -  + ]:CBC         289 :     if (strcmp(aggdeserialfn, "-") != 0)
 2866 rhaas@postgresql.org    14456                 :UBC           0 :         appendPQExpBuffer(details, ",\n    DESERIALFUNC = %s", aggdeserialfn);
                              14457                 :                : 
 3655 tgl@sss.pgh.pa.us       14458         [ +  + ]:CBC         289 :     if (strcmp(aggmtransfn, "-") != 0)
                              14459                 :                :     {
                              14460                 :             30 :         appendPQExpBuffer(details, ",\n    MSFUNC = %s,\n    MINVFUNC = %s,\n    MSTYPE = %s",
                              14461                 :                :                           aggmtransfn,
                              14462                 :                :                           aggminvtransfn,
                              14463                 :                :                           aggmtranstype);
                              14464                 :                :     }
                              14465                 :                : 
                              14466         [ -  + ]:            289 :     if (strcmp(aggmtransspace, "0") != 0)
                              14467                 :                :     {
 3655 tgl@sss.pgh.pa.us       14468                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MSSPACE = %s",
                              14469                 :                :                           aggmtransspace);
                              14470                 :                :     }
                              14471                 :                : 
 3655 tgl@sss.pgh.pa.us       14472         [ +  + ]:CBC         289 :     if (!PQgetisnull(res, 0, i_aggminitval))
                              14473                 :                :     {
                              14474                 :             10 :         appendPQExpBufferStr(details, ",\n    MINITCOND = ");
                              14475                 :             10 :         appendStringLiteralAH(details, aggminitval, fout);
                              14476                 :                :     }
                              14477                 :                : 
                              14478         [ -  + ]:            289 :     if (strcmp(aggmfinalfn, "-") != 0)
                              14479                 :                :     {
 3655 tgl@sss.pgh.pa.us       14480                 :UBC           0 :         appendPQExpBuffer(details, ",\n    MFINALFUNC = %s",
                              14481                 :                :                           aggmfinalfn);
 3644                         14482         [ #  # ]:              0 :         if (aggmfinalextra)
                              14483                 :              0 :             appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
 2374                         14484         [ #  # ]:              0 :         if (aggmfinalmodify != defaultfinalmodify)
                              14485                 :                :         {
                              14486   [ #  #  #  # ]:              0 :             switch (aggmfinalmodify)
                              14487                 :                :             {
                              14488                 :              0 :                 case AGGMODIFY_READ_ONLY:
                              14489                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_ONLY");
                              14490                 :              0 :                     break;
 2155                         14491                 :              0 :                 case AGGMODIFY_SHAREABLE:
                              14492                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = SHAREABLE");
 2374                         14493                 :              0 :                     break;
                              14494                 :              0 :                 case AGGMODIFY_READ_WRITE:
                              14495                 :              0 :                     appendPQExpBufferStr(details, ",\n    MFINALFUNC_MODIFY = READ_WRITE");
                              14496                 :              0 :                     break;
                              14497                 :              0 :                 default:
  737                         14498                 :              0 :                     pg_fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"",
                              14499                 :                :                              agginfo->aggfn.dobj.name);
                              14500                 :                :                     break;
                              14501                 :                :             }
                              14502                 :                :         }
                              14503                 :                :     }
                              14504                 :                : 
 1328 peter@eisentraut.org    14505                 :CBC         289 :     aggsortconvop = getFormattedOperatorName(aggsortop);
 3697 sfrost@snowman.net      14506         [ -  + ]:            289 :     if (aggsortconvop)
                              14507                 :                :     {
 6942 tgl@sss.pgh.pa.us       14508                 :UBC           0 :         appendPQExpBuffer(details, ",\n    SORTOP = %s",
                              14509                 :                :                           aggsortconvop);
 3697 sfrost@snowman.net      14510                 :              0 :         free(aggsortconvop);
                              14511                 :                :     }
                              14512                 :                : 
 2374 tgl@sss.pgh.pa.us       14513         [ +  + ]:CBC         289 :     if (aggkind == AGGKIND_HYPOTHETICAL)
 3765                         14514                 :              5 :         appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
                              14515                 :                : 
 1369 peter@eisentraut.org    14516         [ +  + ]:            289 :     if (proparallel[0] != PROPARALLEL_UNSAFE)
                              14517                 :                :     {
 2916 rhaas@postgresql.org    14518         [ +  - ]:              5 :         if (proparallel[0] == PROPARALLEL_SAFE)
                              14519                 :              5 :             appendPQExpBufferStr(details, ",\n    PARALLEL = safe");
 2916 rhaas@postgresql.org    14520         [ #  # ]:UBC           0 :         else if (proparallel[0] == PROPARALLEL_RESTRICTED)
                              14521                 :              0 :             appendPQExpBufferStr(details, ",\n    PARALLEL = restricted");
                              14522         [ #  # ]:              0 :         else if (proparallel[0] != PROPARALLEL_UNSAFE)
  737 tgl@sss.pgh.pa.us       14523                 :              0 :             pg_fatal("unrecognized proparallel value for function \"%s\"",
                              14524                 :                :                      agginfo->aggfn.dobj.name);
                              14525                 :                :     }
                              14526                 :                : 
 7992 tgl@sss.pgh.pa.us       14527                 :CBC         289 :     appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n",
 7347                         14528                 :            289 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              14529                 :                :                       aggsig);
                              14530                 :                : 
 2239                         14531         [ +  - ]:            578 :     appendPQExpBuffer(q, "CREATE AGGREGATE %s.%s (\n%s\n);\n",
                              14532                 :            289 :                       fmtId(agginfo->aggfn.dobj.namespace->dobj.name),
                              14533                 :                :                       aggfullsig ? aggfullsig : aggsig, details->data);
                              14534                 :                : 
 3470 alvherre@alvh.no-ip.    14535         [ +  + ]:            289 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14536                 :             49 :         binary_upgrade_extension_member(q, &agginfo->aggfn.dobj,
                              14537                 :                :                                         "AGGREGATE", aggsig,
                              14538                 :             49 :                                         agginfo->aggfn.dobj.namespace->dobj.name);
                              14539                 :                : 
 2930 sfrost@snowman.net      14540         [ +  + ]:            289 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14541                 :            272 :         ArchiveEntry(fout, agginfo->aggfn.dobj.catId,
                              14542                 :            272 :                      agginfo->aggfn.dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14543                 :            272 :                      ARCHIVE_OPTS(.tag = aggsig_tag,
                              14544                 :                :                                   .namespace = agginfo->aggfn.dobj.namespace->dobj.name,
                              14545                 :                :                                   .owner = agginfo->aggfn.rolname,
                              14546                 :                :                                   .description = "AGGREGATE",
                              14547                 :                :                                   .section = SECTION_PRE_DATA,
                              14548                 :                :                                   .createStmt = q->data,
                              14549                 :                :                                   .dropStmt = delq->data));
                              14550                 :                : 
                              14551                 :                :     /* Dump Aggregate Comments */
 2930 sfrost@snowman.net      14552         [ +  + ]:            289 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14553                 :             10 :         dumpComment(fout, "AGGREGATE", aggsig,
 2930 sfrost@snowman.net      14554                 :             10 :                     agginfo->aggfn.dobj.namespace->dobj.name,
                              14555                 :             10 :                     agginfo->aggfn.rolname,
                              14556                 :             10 :                     agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              14557                 :                : 
                              14558         [ -  + ]:            289 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       14559                 :UBC           0 :         dumpSecLabel(fout, "AGGREGATE", aggsig,
 2930 sfrost@snowman.net      14560                 :              0 :                      agginfo->aggfn.dobj.namespace->dobj.name,
                              14561                 :              0 :                      agginfo->aggfn.rolname,
 2489 tgl@sss.pgh.pa.us       14562                 :              0 :                      agginfo->aggfn.dobj.catId, 0, agginfo->aggfn.dobj.dumpId);
                              14563                 :                : 
                              14564                 :                :     /*
                              14565                 :                :      * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
                              14566                 :                :      * command look like a function's GRANT; in particular this affects the
                              14567                 :                :      * syntax for zero-argument aggregates and ordered-set aggregates.
                              14568                 :                :      */
 7435 tgl@sss.pgh.pa.us       14569                 :CBC         289 :     free(aggsig);
                              14570                 :                : 
 4451 rhaas@postgresql.org    14571                 :            289 :     aggsig = format_function_signature(fout, &agginfo->aggfn, true);
                              14572                 :                : 
 2930 sfrost@snowman.net      14573         [ +  + ]:            289 :     if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       14574                 :             18 :         dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
                              14575                 :                :                 "FUNCTION", aggsig, NULL,
 2930 sfrost@snowman.net      14576                 :             18 :                 agginfo->aggfn.dobj.namespace->dobj.name,
   13 tgl@sss.pgh.pa.us       14577                 :GNC          18 :                 NULL, agginfo->aggfn.rolname, &agginfo->aggfn.dacl);
                              14578                 :                : 
 7435 tgl@sss.pgh.pa.us       14579                 :CBC         289 :     free(aggsig);
  668 peter@eisentraut.org    14580                 :            289 :     free(aggfullsig);
 7435 tgl@sss.pgh.pa.us       14581                 :            289 :     free(aggsig_tag);
                              14582                 :                : 
 8010                         14583                 :            289 :     PQclear(res);
                              14584                 :                : 
                              14585                 :            289 :     destroyPQExpBuffer(query);
 8290                         14586                 :            289 :     destroyPQExpBuffer(q);
                              14587                 :            289 :     destroyPQExpBuffer(delq);
                              14588                 :            289 :     destroyPQExpBuffer(details);
                              14589                 :                : }
                              14590                 :                : 
                              14591                 :                : /*
                              14592                 :                :  * dumpTSParser
                              14593                 :                :  *    write out a single text search parser
                              14594                 :                :  */
                              14595                 :                : static void
 1159 peter@eisentraut.org    14596                 :             40 : dumpTSParser(Archive *fout, const TSParserInfo *prsinfo)
                              14597                 :                : {
 3014 tgl@sss.pgh.pa.us       14598                 :             40 :     DumpOptions *dopt = fout->dopt;
                              14599                 :                :     PQExpBuffer q;
                              14600                 :                :     PQExpBuffer delq;
                              14601                 :                :     char       *qprsname;
                              14602                 :                : 
                              14603                 :                :     /* Do nothing in data-only dump */
  860                         14604         [ +  + ]:             40 :     if (dopt->dataOnly)
 6081                         14605                 :              3 :         return;
                              14606                 :                : 
                              14607                 :             37 :     q = createPQExpBuffer();
                              14608                 :             37 :     delq = createPQExpBuffer();
                              14609                 :                : 
 2239                         14610                 :             37 :     qprsname = pg_strdup(fmtId(prsinfo->dobj.name));
                              14611                 :                : 
 6081                         14612                 :             37 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
 2239                         14613                 :             37 :                       fmtQualifiedDumpable(prsinfo));
                              14614                 :                : 
 6081                         14615                 :             37 :     appendPQExpBuffer(q, "    START = %s,\n",
 4450 rhaas@postgresql.org    14616                 :             37 :                       convertTSFunction(fout, prsinfo->prsstart));
 6081 tgl@sss.pgh.pa.us       14617                 :             37 :     appendPQExpBuffer(q, "    GETTOKEN = %s,\n",
 4450 rhaas@postgresql.org    14618                 :             37 :                       convertTSFunction(fout, prsinfo->prstoken));
 6081 tgl@sss.pgh.pa.us       14619                 :             37 :     appendPQExpBuffer(q, "    END = %s,\n",
 4450 rhaas@postgresql.org    14620                 :             37 :                       convertTSFunction(fout, prsinfo->prsend));
 6081 tgl@sss.pgh.pa.us       14621         [ +  + ]:             37 :     if (prsinfo->prsheadline != InvalidOid)
                              14622                 :              1 :         appendPQExpBuffer(q, "    HEADLINE = %s,\n",
 4450 rhaas@postgresql.org    14623                 :              1 :                           convertTSFunction(fout, prsinfo->prsheadline));
 6081 tgl@sss.pgh.pa.us       14624                 :             37 :     appendPQExpBuffer(q, "    LEXTYPES = %s );\n",
 4450 rhaas@postgresql.org    14625                 :             37 :                       convertTSFunction(fout, prsinfo->prslextype));
                              14626                 :                : 
 2239 tgl@sss.pgh.pa.us       14627                 :             37 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s;\n",
                              14628                 :             37 :                       fmtQualifiedDumpable(prsinfo));
                              14629                 :                : 
 3470 alvherre@alvh.no-ip.    14630         [ +  + ]:             37 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14631                 :              1 :         binary_upgrade_extension_member(q, &prsinfo->dobj,
                              14632                 :                :                                         "TEXT SEARCH PARSER", qprsname,
                              14633                 :              1 :                                         prsinfo->dobj.namespace->dobj.name);
                              14634                 :                : 
 2930 sfrost@snowman.net      14635         [ +  - ]:             37 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14636                 :             37 :         ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14637                 :             37 :                      ARCHIVE_OPTS(.tag = prsinfo->dobj.name,
                              14638                 :                :                                   .namespace = prsinfo->dobj.namespace->dobj.name,
                              14639                 :                :                                   .description = "TEXT SEARCH PARSER",
                              14640                 :                :                                   .section = SECTION_PRE_DATA,
                              14641                 :                :                                   .createStmt = q->data,
                              14642                 :                :                                   .dropStmt = delq->data));
                              14643                 :                : 
                              14644                 :                :     /* Dump Parser Comments */
 2930 sfrost@snowman.net      14645         [ +  - ]:             37 :     if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14646                 :             37 :         dumpComment(fout, "TEXT SEARCH PARSER", qprsname,
 2596                         14647                 :             37 :                     prsinfo->dobj.namespace->dobj.name, "",
 2930 sfrost@snowman.net      14648                 :             37 :                     prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
                              14649                 :                : 
 6081 tgl@sss.pgh.pa.us       14650                 :             37 :     destroyPQExpBuffer(q);
                              14651                 :             37 :     destroyPQExpBuffer(delq);
 2239                         14652                 :             37 :     free(qprsname);
                              14653                 :                : }
                              14654                 :                : 
                              14655                 :                : /*
                              14656                 :                :  * dumpTSDictionary
                              14657                 :                :  *    write out a single text search dictionary
                              14658                 :                :  */
                              14659                 :                : static void
 1159 peter@eisentraut.org    14660                 :            113 : dumpTSDictionary(Archive *fout, const TSDictInfo *dictinfo)
                              14661                 :                : {
 3014 tgl@sss.pgh.pa.us       14662                 :            113 :     DumpOptions *dopt = fout->dopt;
                              14663                 :                :     PQExpBuffer q;
                              14664                 :                :     PQExpBuffer delq;
                              14665                 :                :     PQExpBuffer query;
                              14666                 :                :     char       *qdictname;
                              14667                 :                :     PGresult   *res;
                              14668                 :                :     char       *nspname;
                              14669                 :                :     char       *tmplname;
                              14670                 :                : 
                              14671                 :                :     /* Do nothing in data-only dump */
  860                         14672         [ +  + ]:            113 :     if (dopt->dataOnly)
 6081                         14673                 :              3 :         return;
                              14674                 :                : 
                              14675                 :            110 :     q = createPQExpBuffer();
                              14676                 :            110 :     delq = createPQExpBuffer();
                              14677                 :            110 :     query = createPQExpBuffer();
                              14678                 :                : 
 2239                         14679                 :            110 :     qdictname = pg_strdup(fmtId(dictinfo->dobj.name));
                              14680                 :                : 
                              14681                 :                :     /* Fetch name and namespace of the dictionary's template */
 6081                         14682                 :            110 :     appendPQExpBuffer(query, "SELECT nspname, tmplname "
                              14683                 :                :                       "FROM pg_ts_template p, pg_namespace n "
                              14684                 :                :                       "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
                              14685                 :            110 :                       dictinfo->dicttemplate);
 4441 rhaas@postgresql.org    14686                 :            110 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6081 tgl@sss.pgh.pa.us       14687                 :            110 :     nspname = PQgetvalue(res, 0, 0);
                              14688                 :            110 :     tmplname = PQgetvalue(res, 0, 1);
                              14689                 :                : 
                              14690                 :            110 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
 2239                         14691                 :            110 :                       fmtQualifiedDumpable(dictinfo));
                              14692                 :                : 
 3800 heikki.linnakangas@i    14693                 :            110 :     appendPQExpBufferStr(q, "    TEMPLATE = ");
 2239 tgl@sss.pgh.pa.us       14694                 :            110 :     appendPQExpBuffer(q, "%s.", fmtId(nspname));
 3800 heikki.linnakangas@i    14695                 :            110 :     appendPQExpBufferStr(q, fmtId(tmplname));
                              14696                 :                : 
 6081 tgl@sss.pgh.pa.us       14697                 :            110 :     PQclear(res);
                              14698                 :                : 
                              14699                 :                :     /* the dictinitoption can be dumped straight into the command */
                              14700         [ +  + ]:            110 :     if (dictinfo->dictinitoption)
 6080                         14701                 :             73 :         appendPQExpBuffer(q, ",\n    %s", dictinfo->dictinitoption);
                              14702                 :                : 
 3800 heikki.linnakangas@i    14703                 :            110 :     appendPQExpBufferStr(q, " );\n");
                              14704                 :                : 
 2239 tgl@sss.pgh.pa.us       14705                 :            110 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s;\n",
                              14706                 :            110 :                       fmtQualifiedDumpable(dictinfo));
                              14707                 :                : 
 3470 alvherre@alvh.no-ip.    14708         [ +  + ]:            110 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14709                 :             10 :         binary_upgrade_extension_member(q, &dictinfo->dobj,
                              14710                 :                :                                         "TEXT SEARCH DICTIONARY", qdictname,
                              14711                 :             10 :                                         dictinfo->dobj.namespace->dobj.name);
                              14712                 :                : 
 2930 sfrost@snowman.net      14713         [ +  - ]:            110 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14714                 :            110 :         ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14715                 :            110 :                      ARCHIVE_OPTS(.tag = dictinfo->dobj.name,
                              14716                 :                :                                   .namespace = dictinfo->dobj.namespace->dobj.name,
                              14717                 :                :                                   .owner = dictinfo->rolname,
                              14718                 :                :                                   .description = "TEXT SEARCH DICTIONARY",
                              14719                 :                :                                   .section = SECTION_PRE_DATA,
                              14720                 :                :                                   .createStmt = q->data,
                              14721                 :                :                                   .dropStmt = delq->data));
                              14722                 :                : 
                              14723                 :                :     /* Dump Dictionary Comments */
 2930 sfrost@snowman.net      14724         [ +  + ]:            110 :     if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14725                 :             65 :         dumpComment(fout, "TEXT SEARCH DICTIONARY", qdictname,
 2596                         14726                 :             65 :                     dictinfo->dobj.namespace->dobj.name, dictinfo->rolname,
 2930 sfrost@snowman.net      14727                 :             65 :                     dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
                              14728                 :                : 
 6081 tgl@sss.pgh.pa.us       14729                 :            110 :     destroyPQExpBuffer(q);
                              14730                 :            110 :     destroyPQExpBuffer(delq);
                              14731                 :            110 :     destroyPQExpBuffer(query);
 2239                         14732                 :            110 :     free(qdictname);
                              14733                 :                : }
                              14734                 :                : 
                              14735                 :                : /*
                              14736                 :                :  * dumpTSTemplate
                              14737                 :                :  *    write out a single text search template
                              14738                 :                :  */
                              14739                 :                : static void
 1159 peter@eisentraut.org    14740                 :             44 : dumpTSTemplate(Archive *fout, const TSTemplateInfo *tmplinfo)
                              14741                 :                : {
 3014 tgl@sss.pgh.pa.us       14742                 :             44 :     DumpOptions *dopt = fout->dopt;
                              14743                 :                :     PQExpBuffer q;
                              14744                 :                :     PQExpBuffer delq;
                              14745                 :                :     char       *qtmplname;
                              14746                 :                : 
                              14747                 :                :     /* Do nothing in data-only dump */
  860                         14748         [ +  + ]:             44 :     if (dopt->dataOnly)
 6081                         14749                 :              3 :         return;
                              14750                 :                : 
                              14751                 :             41 :     q = createPQExpBuffer();
                              14752                 :             41 :     delq = createPQExpBuffer();
                              14753                 :                : 
 2239                         14754                 :             41 :     qtmplname = pg_strdup(fmtId(tmplinfo->dobj.name));
                              14755                 :                : 
 6081                         14756                 :             41 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
 2239                         14757                 :             41 :                       fmtQualifiedDumpable(tmplinfo));
                              14758                 :                : 
 6081                         14759         [ +  + ]:             41 :     if (tmplinfo->tmplinit != InvalidOid)
                              14760                 :              5 :         appendPQExpBuffer(q, "    INIT = %s,\n",
 4450 rhaas@postgresql.org    14761                 :              5 :                           convertTSFunction(fout, tmplinfo->tmplinit));
 6081 tgl@sss.pgh.pa.us       14762                 :             41 :     appendPQExpBuffer(q, "    LEXIZE = %s );\n",
 4450 rhaas@postgresql.org    14763                 :             41 :                       convertTSFunction(fout, tmplinfo->tmpllexize));
                              14764                 :                : 
 2239 tgl@sss.pgh.pa.us       14765                 :             41 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s;\n",
                              14766                 :             41 :                       fmtQualifiedDumpable(tmplinfo));
                              14767                 :                : 
 3470 alvherre@alvh.no-ip.    14768         [ +  + ]:             41 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14769                 :              1 :         binary_upgrade_extension_member(q, &tmplinfo->dobj,
                              14770                 :                :                                         "TEXT SEARCH TEMPLATE", qtmplname,
                              14771                 :              1 :                                         tmplinfo->dobj.namespace->dobj.name);
                              14772                 :                : 
 2930 sfrost@snowman.net      14773         [ +  - ]:             41 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14774                 :             41 :         ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14775                 :             41 :                      ARCHIVE_OPTS(.tag = tmplinfo->dobj.name,
                              14776                 :                :                                   .namespace = tmplinfo->dobj.namespace->dobj.name,
                              14777                 :                :                                   .description = "TEXT SEARCH TEMPLATE",
                              14778                 :                :                                   .section = SECTION_PRE_DATA,
                              14779                 :                :                                   .createStmt = q->data,
                              14780                 :                :                                   .dropStmt = delq->data));
                              14781                 :                : 
                              14782                 :                :     /* Dump Template Comments */
 2930 sfrost@snowman.net      14783         [ +  - ]:             41 :     if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14784                 :             41 :         dumpComment(fout, "TEXT SEARCH TEMPLATE", qtmplname,
 2596                         14785                 :             41 :                     tmplinfo->dobj.namespace->dobj.name, "",
 2930 sfrost@snowman.net      14786                 :             41 :                     tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
                              14787                 :                : 
 6081 tgl@sss.pgh.pa.us       14788                 :             41 :     destroyPQExpBuffer(q);
                              14789                 :             41 :     destroyPQExpBuffer(delq);
 2239                         14790                 :             41 :     free(qtmplname);
                              14791                 :                : }
                              14792                 :                : 
                              14793                 :                : /*
                              14794                 :                :  * dumpTSConfig
                              14795                 :                :  *    write out a single text search configuration
                              14796                 :                :  */
                              14797                 :                : static void
 1159 peter@eisentraut.org    14798                 :             88 : dumpTSConfig(Archive *fout, const TSConfigInfo *cfginfo)
                              14799                 :                : {
 3014 tgl@sss.pgh.pa.us       14800                 :             88 :     DumpOptions *dopt = fout->dopt;
                              14801                 :                :     PQExpBuffer q;
                              14802                 :                :     PQExpBuffer delq;
                              14803                 :                :     PQExpBuffer query;
                              14804                 :                :     char       *qcfgname;
                              14805                 :                :     PGresult   *res;
                              14806                 :                :     char       *nspname;
                              14807                 :                :     char       *prsname;
                              14808                 :                :     int         ntups,
                              14809                 :                :                 i;
                              14810                 :                :     int         i_tokenname;
                              14811                 :                :     int         i_dictname;
                              14812                 :                : 
                              14813                 :                :     /* Do nothing in data-only dump */
  860                         14814         [ +  + ]:             88 :     if (dopt->dataOnly)
 6081                         14815                 :              3 :         return;
                              14816                 :                : 
                              14817                 :             85 :     q = createPQExpBuffer();
                              14818                 :             85 :     delq = createPQExpBuffer();
                              14819                 :             85 :     query = createPQExpBuffer();
                              14820                 :                : 
 2239                         14821                 :             85 :     qcfgname = pg_strdup(fmtId(cfginfo->dobj.name));
                              14822                 :                : 
                              14823                 :                :     /* Fetch name and namespace of the config's parser */
 6081                         14824                 :             85 :     appendPQExpBuffer(query, "SELECT nspname, prsname "
                              14825                 :                :                       "FROM pg_ts_parser p, pg_namespace n "
                              14826                 :                :                       "WHERE p.oid = '%u' AND n.oid = prsnamespace",
                              14827                 :             85 :                       cfginfo->cfgparser);
 4441 rhaas@postgresql.org    14828                 :             85 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 6081 tgl@sss.pgh.pa.us       14829                 :             85 :     nspname = PQgetvalue(res, 0, 0);
                              14830                 :             85 :     prsname = PQgetvalue(res, 0, 1);
                              14831                 :                : 
                              14832                 :             85 :     appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
 2239                         14833                 :             85 :                       fmtQualifiedDumpable(cfginfo));
                              14834                 :                : 
                              14835                 :             85 :     appendPQExpBuffer(q, "    PARSER = %s.", fmtId(nspname));
 6081                         14836                 :             85 :     appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
                              14837                 :                : 
                              14838                 :             85 :     PQclear(res);
                              14839                 :                : 
                              14840                 :             85 :     resetPQExpBuffer(query);
                              14841                 :             85 :     appendPQExpBuffer(query,
                              14842                 :                :                       "SELECT\n"
                              14843                 :                :                       "  ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t\n"
                              14844                 :                :                       "    WHERE t.tokid = m.maptokentype ) AS tokenname,\n"
                              14845                 :                :                       "  m.mapdict::pg_catalog.regdictionary AS dictname\n"
                              14846                 :                :                       "FROM pg_catalog.pg_ts_config_map AS m\n"
                              14847                 :                :                       "WHERE m.mapcfg = '%u'\n"
                              14848                 :                :                       "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
                              14849                 :             85 :                       cfginfo->cfgparser, cfginfo->dobj.catId.oid);
                              14850                 :                : 
 4450 rhaas@postgresql.org    14851                 :             85 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 6081 tgl@sss.pgh.pa.us       14852                 :             85 :     ntups = PQntuples(res);
                              14853                 :                : 
                              14854                 :             85 :     i_tokenname = PQfnumber(res, "tokenname");
                              14855                 :             85 :     i_dictname = PQfnumber(res, "dictname");
                              14856                 :                : 
                              14857         [ +  + ]:           1835 :     for (i = 0; i < ntups; i++)
                              14858                 :                :     {
 5995 bruce@momjian.us        14859                 :           1750 :         char       *tokenname = PQgetvalue(res, i, i_tokenname);
                              14860                 :           1750 :         char       *dictname = PQgetvalue(res, i, i_dictname);
                              14861                 :                : 
 6081 tgl@sss.pgh.pa.us       14862         [ +  + ]:           1750 :         if (i == 0 ||
 5995 bruce@momjian.us        14863         [ +  + ]:           1665 :             strcmp(tokenname, PQgetvalue(res, i - 1, i_tokenname)) != 0)
                              14864                 :                :         {
                              14865                 :                :             /* starting a new token type, so start a new command */
 6081 tgl@sss.pgh.pa.us       14866         [ +  + ]:           1615 :             if (i > 0)
 3800 heikki.linnakangas@i    14867                 :           1530 :                 appendPQExpBufferStr(q, ";\n");
 6081 tgl@sss.pgh.pa.us       14868                 :           1615 :             appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
 2239                         14869                 :           1615 :                               fmtQualifiedDumpable(cfginfo));
                              14870                 :                :             /* tokenname needs quoting, dictname does NOT */
 6081                         14871                 :           1615 :             appendPQExpBuffer(q, "    ADD MAPPING FOR %s WITH %s",
                              14872                 :                :                               fmtId(tokenname), dictname);
                              14873                 :                :         }
                              14874                 :                :         else
                              14875                 :            135 :             appendPQExpBuffer(q, ", %s", dictname);
                              14876                 :                :     }
                              14877                 :                : 
                              14878         [ +  - ]:             85 :     if (ntups > 0)
 3800 heikki.linnakangas@i    14879                 :             85 :         appendPQExpBufferStr(q, ";\n");
                              14880                 :                : 
 6081 tgl@sss.pgh.pa.us       14881                 :             85 :     PQclear(res);
                              14882                 :                : 
 2239                         14883                 :             85 :     appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s;\n",
                              14884                 :             85 :                       fmtQualifiedDumpable(cfginfo));
                              14885                 :                : 
 3470 alvherre@alvh.no-ip.    14886         [ +  + ]:             85 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14887                 :              5 :         binary_upgrade_extension_member(q, &cfginfo->dobj,
                              14888                 :                :                                         "TEXT SEARCH CONFIGURATION", qcfgname,
                              14889                 :              5 :                                         cfginfo->dobj.namespace->dobj.name);
                              14890                 :                : 
 2930 sfrost@snowman.net      14891         [ +  - ]:             85 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14892                 :             85 :         ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14893                 :             85 :                      ARCHIVE_OPTS(.tag = cfginfo->dobj.name,
                              14894                 :                :                                   .namespace = cfginfo->dobj.namespace->dobj.name,
                              14895                 :                :                                   .owner = cfginfo->rolname,
                              14896                 :                :                                   .description = "TEXT SEARCH CONFIGURATION",
                              14897                 :                :                                   .section = SECTION_PRE_DATA,
                              14898                 :                :                                   .createStmt = q->data,
                              14899                 :                :                                   .dropStmt = delq->data));
                              14900                 :                : 
                              14901                 :                :     /* Dump Configuration Comments */
 2930 sfrost@snowman.net      14902         [ +  + ]:             85 :     if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14903                 :             65 :         dumpComment(fout, "TEXT SEARCH CONFIGURATION", qcfgname,
 2596                         14904                 :             65 :                     cfginfo->dobj.namespace->dobj.name, cfginfo->rolname,
 2930 sfrost@snowman.net      14905                 :             65 :                     cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
                              14906                 :                : 
 6081 tgl@sss.pgh.pa.us       14907                 :             85 :     destroyPQExpBuffer(q);
                              14908                 :             85 :     destroyPQExpBuffer(delq);
                              14909                 :             85 :     destroyPQExpBuffer(query);
 2239                         14910                 :             85 :     free(qcfgname);
                              14911                 :                : }
                              14912                 :                : 
                              14913                 :                : /*
                              14914                 :                :  * dumpForeignDataWrapper
                              14915                 :                :  *    write out a single foreign-data wrapper definition
                              14916                 :                :  */
                              14917                 :                : static void
 1159 peter@eisentraut.org    14918                 :             53 : dumpForeignDataWrapper(Archive *fout, const FdwInfo *fdwinfo)
                              14919                 :                : {
 3014 tgl@sss.pgh.pa.us       14920                 :             53 :     DumpOptions *dopt = fout->dopt;
                              14921                 :                :     PQExpBuffer q;
                              14922                 :                :     PQExpBuffer delq;
                              14923                 :                :     char       *qfdwname;
                              14924                 :                : 
                              14925                 :                :     /* Do nothing in data-only dump */
  860                         14926         [ +  + ]:             53 :     if (dopt->dataOnly)
 5595 peter_e@gmx.net         14927                 :              4 :         return;
                              14928                 :                : 
                              14929                 :             49 :     q = createPQExpBuffer();
                              14930                 :             49 :     delq = createPQExpBuffer();
                              14931                 :                : 
 4524 bruce@momjian.us        14932                 :             49 :     qfdwname = pg_strdup(fmtId(fdwinfo->dobj.name));
                              14933                 :                : 
 5528 peter_e@gmx.net         14934                 :             49 :     appendPQExpBuffer(q, "CREATE FOREIGN DATA WRAPPER %s",
                              14935                 :                :                       qfdwname);
                              14936                 :                : 
 4803 tgl@sss.pgh.pa.us       14937         [ -  + ]:             49 :     if (strcmp(fdwinfo->fdwhandler, "-") != 0)
 4803 tgl@sss.pgh.pa.us       14938                 :UBC           0 :         appendPQExpBuffer(q, " HANDLER %s", fdwinfo->fdwhandler);
                              14939                 :                : 
 4803 tgl@sss.pgh.pa.us       14940         [ -  + ]:CBC          49 :     if (strcmp(fdwinfo->fdwvalidator, "-") != 0)
 4803 tgl@sss.pgh.pa.us       14941                 :UBC           0 :         appendPQExpBuffer(q, " VALIDATOR %s", fdwinfo->fdwvalidator);
                              14942                 :                : 
 4803 tgl@sss.pgh.pa.us       14943         [ -  + ]:CBC          49 :     if (strlen(fdwinfo->fdwoptions) > 0)
 4483 peter_e@gmx.net         14944                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", fdwinfo->fdwoptions);
                              14945                 :                : 
 3800 heikki.linnakangas@i    14946                 :CBC          49 :     appendPQExpBufferStr(q, ";\n");
                              14947                 :                : 
 5595 peter_e@gmx.net         14948                 :             49 :     appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                              14949                 :                :                       qfdwname);
                              14950                 :                : 
 3470 alvherre@alvh.no-ip.    14951         [ +  + ]:             49 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       14952                 :              2 :         binary_upgrade_extension_member(q, &fdwinfo->dobj,
                              14953                 :                :                                         "FOREIGN DATA WRAPPER", qfdwname,
                              14954                 :                :                                         NULL);
                              14955                 :                : 
 2930 sfrost@snowman.net      14956         [ +  - ]:             49 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              14957                 :             49 :         ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    14958                 :             49 :                      ARCHIVE_OPTS(.tag = fdwinfo->dobj.name,
                              14959                 :                :                                   .owner = fdwinfo->rolname,
                              14960                 :                :                                   .description = "FOREIGN DATA WRAPPER",
                              14961                 :                :                                   .section = SECTION_PRE_DATA,
                              14962                 :                :                                   .createStmt = q->data,
                              14963                 :                :                                   .dropStmt = delq->data));
                              14964                 :                : 
                              14965                 :                :     /* Dump Foreign Data Wrapper Comments */
 2274 tgl@sss.pgh.pa.us       14966         [ -  + ]:             49 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       14967                 :UBC           0 :         dumpComment(fout, "FOREIGN DATA WRAPPER", qfdwname,
 2274                         14968                 :              0 :                     NULL, fdwinfo->rolname,
                              14969                 :              0 :                     fdwinfo->dobj.catId, 0, fdwinfo->dobj.dumpId);
                              14970                 :                : 
                              14971                 :                :     /* Handle the ACL */
 2930 sfrost@snowman.net      14972         [ +  + ]:CBC          49 :     if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       14973                 :             35 :         dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
                              14974                 :                :                 "FOREIGN DATA WRAPPER", qfdwname, NULL, NULL,
  860                         14975                 :             35 :                 NULL, fdwinfo->rolname, &fdwinfo->dacl);
                              14976                 :                : 
 4813                         14977                 :             49 :     free(qfdwname);
                              14978                 :                : 
 5595 peter_e@gmx.net         14979                 :             49 :     destroyPQExpBuffer(q);
                              14980                 :             49 :     destroyPQExpBuffer(delq);
                              14981                 :                : }
                              14982                 :                : 
                              14983                 :                : /*
                              14984                 :                :  * dumpForeignServer
                              14985                 :                :  *    write out a foreign server definition
                              14986                 :                :  */
                              14987                 :                : static void
 1159 peter@eisentraut.org    14988                 :             57 : dumpForeignServer(Archive *fout, const ForeignServerInfo *srvinfo)
                              14989                 :                : {
 3014 tgl@sss.pgh.pa.us       14990                 :             57 :     DumpOptions *dopt = fout->dopt;
                              14991                 :                :     PQExpBuffer q;
                              14992                 :                :     PQExpBuffer delq;
                              14993                 :                :     PQExpBuffer query;
                              14994                 :                :     PGresult   *res;
                              14995                 :                :     char       *qsrvname;
                              14996                 :                :     char       *fdwname;
                              14997                 :                : 
                              14998                 :                :     /* Do nothing in data-only dump */
  860                         14999         [ +  + ]:             57 :     if (dopt->dataOnly)
 5595 peter_e@gmx.net         15000                 :              6 :         return;
                              15001                 :                : 
                              15002                 :             51 :     q = createPQExpBuffer();
                              15003                 :             51 :     delq = createPQExpBuffer();
                              15004                 :             51 :     query = createPQExpBuffer();
                              15005                 :                : 
 4524 bruce@momjian.us        15006                 :             51 :     qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
                              15007                 :                : 
                              15008                 :                :     /* look up the foreign-data wrapper */
 5595 peter_e@gmx.net         15009                 :             51 :     appendPQExpBuffer(query, "SELECT fdwname "
                              15010                 :                :                       "FROM pg_foreign_data_wrapper w "
                              15011                 :                :                       "WHERE w.oid = '%u'",
                              15012                 :             51 :                       srvinfo->srvfdw);
 4441 rhaas@postgresql.org    15013                 :             51 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
 5595 peter_e@gmx.net         15014                 :             51 :     fdwname = PQgetvalue(res, 0, 0);
                              15015                 :                : 
 4813 tgl@sss.pgh.pa.us       15016                 :             51 :     appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
 5595 peter_e@gmx.net         15017   [ +  -  -  + ]:             51 :     if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
                              15018                 :                :     {
 3800 heikki.linnakangas@i    15019                 :UBC           0 :         appendPQExpBufferStr(q, " TYPE ");
 5485                         15020                 :              0 :         appendStringLiteralAH(q, srvinfo->srvtype, fout);
                              15021                 :                :     }
 5595 peter_e@gmx.net         15022   [ +  -  -  + ]:CBC          51 :     if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
                              15023                 :                :     {
 3800 heikki.linnakangas@i    15024                 :UBC           0 :         appendPQExpBufferStr(q, " VERSION ");
 5485                         15025                 :              0 :         appendStringLiteralAH(q, srvinfo->srvversion, fout);
                              15026                 :                :     }
                              15027                 :                : 
 3800 heikki.linnakangas@i    15028                 :CBC          51 :     appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
                              15029                 :             51 :     appendPQExpBufferStr(q, fmtId(fdwname));
                              15030                 :                : 
 5595 peter_e@gmx.net         15031   [ +  -  -  + ]:             51 :     if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
 4483 peter_e@gmx.net         15032                 :UBC           0 :         appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", srvinfo->srvoptions);
                              15033                 :                : 
 3800 heikki.linnakangas@i    15034                 :CBC          51 :     appendPQExpBufferStr(q, ";\n");
                              15035                 :                : 
 5595 peter_e@gmx.net         15036                 :             51 :     appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                              15037                 :                :                       qsrvname);
                              15038                 :                : 
 3470 alvherre@alvh.no-ip.    15039         [ +  + ]:             51 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       15040                 :              2 :         binary_upgrade_extension_member(q, &srvinfo->dobj,
                              15041                 :                :                                         "SERVER", qsrvname, NULL);
                              15042                 :                : 
 2930 sfrost@snowman.net      15043         [ +  - ]:             51 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15044                 :             51 :         ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    15045                 :             51 :                      ARCHIVE_OPTS(.tag = srvinfo->dobj.name,
                              15046                 :                :                                   .owner = srvinfo->rolname,
                              15047                 :                :                                   .description = "SERVER",
                              15048                 :                :                                   .section = SECTION_PRE_DATA,
                              15049                 :                :                                   .createStmt = q->data,
                              15050                 :                :                                   .dropStmt = delq->data));
                              15051                 :                : 
                              15052                 :                :     /* Dump Foreign Server Comments */
 2274 tgl@sss.pgh.pa.us       15053         [ -  + ]:             51 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       15054                 :UBC           0 :         dumpComment(fout, "SERVER", qsrvname,
 2274                         15055                 :              0 :                     NULL, srvinfo->rolname,
                              15056                 :              0 :                     srvinfo->dobj.catId, 0, srvinfo->dobj.dumpId);
                              15057                 :                : 
                              15058                 :                :     /* Handle the ACL */
 2930 sfrost@snowman.net      15059         [ +  + ]:CBC          51 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
 1373 tgl@sss.pgh.pa.us       15060                 :             35 :         dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
                              15061                 :                :                 "FOREIGN SERVER", qsrvname, NULL, NULL,
  860                         15062                 :             35 :                 NULL, srvinfo->rolname, &srvinfo->dacl);
                              15063                 :                : 
                              15064                 :                :     /* Dump user mappings */
 2930 sfrost@snowman.net      15065         [ +  - ]:             51 :     if (srvinfo->dobj.dump & DUMP_COMPONENT_USERMAP)
                              15066                 :             51 :         dumpUserMappings(fout,
                              15067                 :             51 :                          srvinfo->dobj.name, NULL,
                              15068                 :             51 :                          srvinfo->rolname,
                              15069                 :             51 :                          srvinfo->dobj.catId, srvinfo->dobj.dumpId);
                              15070                 :                : 
  903 tgl@sss.pgh.pa.us       15071                 :             51 :     PQclear(res);
                              15072                 :                : 
 4813                         15073                 :             51 :     free(qsrvname);
                              15074                 :                : 
 5595 peter_e@gmx.net         15075                 :             51 :     destroyPQExpBuffer(q);
                              15076                 :             51 :     destroyPQExpBuffer(delq);
 2925 tgl@sss.pgh.pa.us       15077                 :             51 :     destroyPQExpBuffer(query);
                              15078                 :                : }
                              15079                 :                : 
                              15080                 :                : /*
                              15081                 :                :  * dumpUserMappings
                              15082                 :                :  *
                              15083                 :                :  * This routine is used to dump any user mappings associated with the
                              15084                 :                :  * server handed to this routine. Should be called after ArchiveEntry()
                              15085                 :                :  * for the server.
                              15086                 :                :  */
                              15087                 :                : static void
 5023                         15088                 :             51 : dumpUserMappings(Archive *fout,
                              15089                 :                :                  const char *servername, const char *namespace,
                              15090                 :                :                  const char *owner,
                              15091                 :                :                  CatalogId catalogId, DumpId dumpId)
                              15092                 :                : {
                              15093                 :                :     PQExpBuffer q;
                              15094                 :                :     PQExpBuffer delq;
                              15095                 :                :     PQExpBuffer query;
                              15096                 :                :     PQExpBuffer tag;
                              15097                 :                :     PGresult   *res;
                              15098                 :                :     int         ntups;
                              15099                 :                :     int         i_usename;
                              15100                 :                :     int         i_umoptions;
                              15101                 :                :     int         i;
                              15102                 :                : 
 5595 peter_e@gmx.net         15103                 :             51 :     q = createPQExpBuffer();
                              15104                 :             51 :     tag = createPQExpBuffer();
                              15105                 :             51 :     delq = createPQExpBuffer();
                              15106                 :             51 :     query = createPQExpBuffer();
                              15107                 :                : 
                              15108                 :                :     /*
                              15109                 :                :      * We read from the publicly accessible view pg_user_mappings, so as not
                              15110                 :                :      * to fail if run by a non-superuser.  Note that the view will show
                              15111                 :                :      * umoptions as null if the user hasn't got privileges for the associated
                              15112                 :                :      * server; this means that pg_dump will dump such a mapping, but with no
                              15113                 :                :      * OPTIONS clause.  A possible alternative is to skip such mappings
                              15114                 :                :      * altogether, but it's not clear that that's an improvement.
                              15115                 :                :      */
                              15116                 :             51 :     appendPQExpBuffer(query,
                              15117                 :                :                       "SELECT usename, "
                              15118                 :                :                       "array_to_string(ARRAY("
                              15119                 :                :                       "SELECT quote_ident(option_name) || ' ' || "
                              15120                 :                :                       "quote_literal(option_value) "
                              15121                 :                :                       "FROM pg_options_to_table(umoptions) "
                              15122                 :                :                       "ORDER BY option_name"
                              15123                 :                :                       "), E',\n    ') AS umoptions "
                              15124                 :                :                       "FROM pg_user_mappings "
                              15125                 :                :                       "WHERE srvid = '%u' "
                              15126                 :                :                       "ORDER BY usename",
                              15127                 :                :                       catalogId.oid);
                              15128                 :                : 
 4450 rhaas@postgresql.org    15129                 :             51 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              15130                 :                : 
 5595 peter_e@gmx.net         15131                 :             51 :     ntups = PQntuples(res);
 5023 tgl@sss.pgh.pa.us       15132                 :             51 :     i_usename = PQfnumber(res, "usename");
 5595 peter_e@gmx.net         15133                 :             51 :     i_umoptions = PQfnumber(res, "umoptions");
                              15134                 :                : 
                              15135         [ +  + ]:             86 :     for (i = 0; i < ntups; i++)
                              15136                 :                :     {
                              15137                 :                :         char       *usename;
                              15138                 :                :         char       *umoptions;
                              15139                 :                : 
 5023 tgl@sss.pgh.pa.us       15140                 :             35 :         usename = PQgetvalue(res, i, i_usename);
 5595 peter_e@gmx.net         15141                 :             35 :         umoptions = PQgetvalue(res, i, i_umoptions);
                              15142                 :                : 
                              15143                 :             35 :         resetPQExpBuffer(q);
 5023 tgl@sss.pgh.pa.us       15144                 :             35 :         appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
 5595 peter_e@gmx.net         15145                 :             35 :         appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
                              15146                 :                : 
                              15147   [ +  -  -  + ]:             35 :         if (umoptions && strlen(umoptions) > 0)
 4483 peter_e@gmx.net         15148                 :UBC           0 :             appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", umoptions);
                              15149                 :                : 
 3800 heikki.linnakangas@i    15150                 :CBC          35 :         appendPQExpBufferStr(q, ";\n");
                              15151                 :                : 
 5595 peter_e@gmx.net         15152                 :             35 :         resetPQExpBuffer(delq);
 5023 tgl@sss.pgh.pa.us       15153                 :             35 :         appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
                              15154                 :             35 :         appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
                              15155                 :                : 
 5595 peter_e@gmx.net         15156                 :             35 :         resetPQExpBuffer(tag);
 5023 tgl@sss.pgh.pa.us       15157                 :             35 :         appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
                              15158                 :                :                           usename, servername);
                              15159                 :                : 
 5595 peter_e@gmx.net         15160                 :             35 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    15161                 :             35 :                      ARCHIVE_OPTS(.tag = tag->data,
                              15162                 :                :                                   .namespace = namespace,
                              15163                 :                :                                   .owner = owner,
                              15164                 :                :                                   .description = "USER MAPPING",
                              15165                 :                :                                   .section = SECTION_PRE_DATA,
                              15166                 :                :                                   .createStmt = q->data,
                              15167                 :                :                                   .dropStmt = delq->data));
                              15168                 :                :     }
                              15169                 :                : 
 5595 peter_e@gmx.net         15170                 :             51 :     PQclear(res);
                              15171                 :                : 
                              15172                 :             51 :     destroyPQExpBuffer(query);
                              15173                 :             51 :     destroyPQExpBuffer(delq);
 3697 sfrost@snowman.net      15174                 :             51 :     destroyPQExpBuffer(tag);
 5595 peter_e@gmx.net         15175                 :             51 :     destroyPQExpBuffer(q);
                              15176                 :             51 : }
                              15177                 :                : 
                              15178                 :                : /*
                              15179                 :                :  * Write out default privileges information
                              15180                 :                :  */
                              15181                 :                : static void
 1159 peter@eisentraut.org    15182                 :            154 : dumpDefaultACL(Archive *fout, const DefaultACLInfo *daclinfo)
                              15183                 :                : {
 3014 tgl@sss.pgh.pa.us       15184                 :            154 :     DumpOptions *dopt = fout->dopt;
                              15185                 :                :     PQExpBuffer q;
                              15186                 :                :     PQExpBuffer tag;
                              15187                 :                :     const char *type;
                              15188                 :                : 
                              15189                 :                :     /* Do nothing in data-only dump, or if we're skipping ACLs */
  860                         15190   [ +  +  +  + ]:            154 :     if (dopt->dataOnly || dopt->aclsSkip)
 5305                         15191                 :             16 :         return;
                              15192                 :                : 
                              15193                 :            138 :     q = createPQExpBuffer();
                              15194                 :            138 :     tag = createPQExpBuffer();
                              15195                 :                : 
                              15196   [ +  -  +  -  :            138 :     switch (daclinfo->defaclobjtype)
                                              -  - ]
                              15197                 :                :     {
                              15198                 :             69 :         case DEFACLOBJ_RELATION:
 5298                         15199                 :             69 :             type = "TABLES";
 5305                         15200                 :             69 :             break;
 5305 tgl@sss.pgh.pa.us       15201                 :UBC           0 :         case DEFACLOBJ_SEQUENCE:
 5298                         15202                 :              0 :             type = "SEQUENCES";
 5305                         15203                 :              0 :             break;
 5305 tgl@sss.pgh.pa.us       15204                 :CBC          69 :         case DEFACLOBJ_FUNCTION:
 5298                         15205                 :             69 :             type = "FUNCTIONS";
 5305                         15206                 :             69 :             break;
 4144 tgl@sss.pgh.pa.us       15207                 :UBC           0 :         case DEFACLOBJ_TYPE:
                              15208                 :              0 :             type = "TYPES";
                              15209                 :              0 :             break;
 2574 teodor@sigaev.ru        15210                 :              0 :         case DEFACLOBJ_NAMESPACE:
                              15211                 :              0 :             type = "SCHEMAS";
                              15212                 :              0 :             break;
 5305 tgl@sss.pgh.pa.us       15213                 :              0 :         default:
                              15214                 :                :             /* shouldn't get here */
  737                         15215                 :              0 :             pg_fatal("unrecognized object type in default privileges: %d",
                              15216                 :                :                      (int) daclinfo->defaclobjtype);
                              15217                 :                :             type = "";            /* keep compiler quiet */
                              15218                 :                :     }
                              15219                 :                : 
 5298 tgl@sss.pgh.pa.us       15220                 :CBC         138 :     appendPQExpBuffer(tag, "DEFAULT PRIVILEGES FOR %s", type);
                              15221                 :                : 
                              15222                 :                :     /* build the actual command(s) for this tuple */
 5305                         15223         [ -  + ]:            138 :     if (!buildDefaultACLCommands(type,
                              15224                 :            138 :                                  daclinfo->dobj.namespace != NULL ?
                              15225                 :             70 :                                  daclinfo->dobj.namespace->dobj.name : NULL,
  860                         15226                 :            138 :                                  daclinfo->dacl.acl,
                              15227                 :            138 :                                  daclinfo->dacl.acldefault,
 5305                         15228         [ +  + ]:            138 :                                  daclinfo->defaclrole,
                              15229                 :                :                                  fout->remoteVersion,
                              15230                 :                :                                  q))
  737 tgl@sss.pgh.pa.us       15231                 :UBC           0 :         pg_fatal("could not parse default ACL list (%s)",
                              15232                 :                :                  daclinfo->dacl.acl);
                              15233                 :                : 
 2930 sfrost@snowman.net      15234         [ +  - ]:CBC         138 :     if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              15235                 :            138 :         ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    15236         [ +  + ]:            138 :                      ARCHIVE_OPTS(.tag = tag->data,
                              15237                 :                :                                   .namespace = daclinfo->dobj.namespace ?
                              15238                 :                :                                   daclinfo->dobj.namespace->dobj.name : NULL,
                              15239                 :                :                                   .owner = daclinfo->defaclrole,
                              15240                 :                :                                   .description = "DEFAULT ACL",
                              15241                 :                :                                   .section = SECTION_POST_DATA,
                              15242                 :                :                                   .createStmt = q->data));
                              15243                 :                : 
 5305 tgl@sss.pgh.pa.us       15244                 :            138 :     destroyPQExpBuffer(tag);
                              15245                 :            138 :     destroyPQExpBuffer(q);
                              15246                 :                : }
                              15247                 :                : 
                              15248                 :                : /*----------
                              15249                 :                :  * Write out grant/revoke information
                              15250                 :                :  *
                              15251                 :                :  * 'objDumpId' is the dump ID of the underlying object.
                              15252                 :                :  * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
                              15253                 :                :  *      or InvalidDumpId if there is no need for a second dependency.
                              15254                 :                :  * 'type' must be one of
                              15255                 :                :  *      TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
                              15256                 :                :  *      FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
                              15257                 :                :  * 'name' is the formatted name of the object.  Must be quoted etc. already.
                              15258                 :                :  * 'subname' is the formatted name of the sub-object, if any.  Must be quoted.
                              15259                 :                :  *      (Currently we assume that subname is only provided for table columns.)
                              15260                 :                :  * 'nspname' is the namespace the object is in (NULL if none).
                              15261                 :                :  * 'tag' is the tag to use for the ACL TOC entry; typically, this is NULL
                              15262                 :                :  *      to use the default for the object type.
                              15263                 :                :  * 'owner' is the owner, NULL if there is no owner (for languages).
                              15264                 :                :  * 'dacl' is the DumpableAcl struct for the object.
                              15265                 :                :  *
                              15266                 :                :  * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
                              15267                 :                :  * no ACL entry was created.
                              15268                 :                :  *----------
                              15269                 :                :  */
                              15270                 :                : static DumpId
 1373                         15271                 :          23222 : dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
                              15272                 :                :         const char *type, const char *name, const char *subname,
                              15273                 :                :         const char *nspname, const char *tag, const char *owner,
                              15274                 :                :         const DumpableAcl *dacl)
                              15275                 :                : {
                              15276                 :          23222 :     DumpId      aclDumpId = InvalidDumpId;
 3014                         15277                 :          23222 :     DumpOptions *dopt = fout->dopt;
  860                         15278                 :          23222 :     const char *acls = dacl->acl;
                              15279                 :          23222 :     const char *acldefault = dacl->acldefault;
                              15280                 :          23222 :     char        privtype = dacl->privtype;
                              15281                 :          23222 :     const char *initprivs = dacl->initprivs;
                              15282                 :                :     const char *baseacls;
                              15283                 :                :     PQExpBuffer sql;
                              15284                 :                : 
                              15285                 :                :     /* Do nothing if ACL dump is not enabled */
 3470 alvherre@alvh.no-ip.    15286         [ +  + ]:          23222 :     if (dopt->aclsSkip)
 1373 tgl@sss.pgh.pa.us       15287                 :            318 :         return InvalidDumpId;
                              15288                 :                : 
                              15289                 :                :     /* --data-only skips ACLs *except* large object ACLs */
 3470 alvherre@alvh.no-ip.    15290   [ +  +  -  + ]:          22904 :     if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
 1373 tgl@sss.pgh.pa.us       15291                 :UBC           0 :         return InvalidDumpId;
                              15292                 :                : 
 8014 tgl@sss.pgh.pa.us       15293                 :CBC       22904 :     sql = createPQExpBuffer();
                              15294                 :                : 
                              15295                 :                :     /*
                              15296                 :                :      * In binary upgrade mode, we don't run an extension's script but instead
                              15297                 :                :      * dump out the objects independently and then recreate them.  To preserve
                              15298                 :                :      * any initial privileges which were set on extension objects, we need to
                              15299                 :                :      * compute the set of GRANT and REVOKE commands necessary to get from the
                              15300                 :                :      * default privileges of an object to its initial privileges as recorded
                              15301                 :                :      * in pg_init_privs.
                              15302                 :                :      *
                              15303                 :                :      * At restore time, we apply these commands after having called
                              15304                 :                :      * binary_upgrade_set_record_init_privs(true).  That tells the backend to
                              15305                 :                :      * copy the results into pg_init_privs.  This is how we preserve the
                              15306                 :                :      * contents of that catalog across binary upgrades.
                              15307                 :                :      */
  860                         15308   [ +  +  +  +  :          22904 :     if (dopt->binary_upgrade && privtype == 'e' &&
                                              +  - ]
                              15309         [ +  - ]:             13 :         initprivs && *initprivs != '\0')
                              15310                 :                :     {
 1746 drowley@postgresql.o    15311                 :             13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n");
 2239 tgl@sss.pgh.pa.us       15312         [ -  + ]:             13 :         if (!buildACLCommands(name, subname, nspname, type,
                              15313                 :                :                               initprivs, acldefault, owner,
                              15314                 :                :                               "", fout->remoteVersion, sql))
  737 tgl@sss.pgh.pa.us       15315                 :UBC           0 :             pg_fatal("could not parse initial ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              15316                 :                :                      initprivs, acldefault, name, type);
 1746 drowley@postgresql.o    15317                 :CBC          13 :         appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n");
                              15318                 :                :     }
                              15319                 :                : 
                              15320                 :                :     /*
                              15321                 :                :      * Now figure the GRANT and REVOKE commands needed to get to the object's
                              15322                 :                :      * actual current ACL, starting from the initprivs if given, else from the
                              15323                 :                :      * object-type-specific default.  Also, while buildACLCommands will assume
                              15324                 :                :      * that a NULL/empty acls string means it needn't do anything, what that
                              15325                 :                :      * actually represents is the object-type-specific default; so we need to
                              15326                 :                :      * substitute the acldefault string to get the right results in that case.
                              15327                 :                :      */
  860 tgl@sss.pgh.pa.us       15328   [ +  +  +  + ]:          22904 :     if (initprivs && *initprivs != '\0')
                              15329                 :                :     {
                              15330                 :          21021 :         baseacls = initprivs;
                              15331   [ +  -  +  + ]:          21021 :         if (acls == NULL || *acls == '\0')
                              15332                 :             17 :             acls = acldefault;
                              15333                 :                :     }
                              15334                 :                :     else
                              15335                 :           1883 :         baseacls = acldefault;
                              15336                 :                : 
 2239                         15337         [ -  + ]:          22904 :     if (!buildACLCommands(name, subname, nspname, type,
                              15338                 :                :                           acls, baseacls, owner,
                              15339                 :                :                           "", fout->remoteVersion, sql))
  737 tgl@sss.pgh.pa.us       15340                 :UBC           0 :         pg_fatal("could not parse ACL list (%s) or default (%s) for object \"%s\" (%s)",
                              15341                 :                :                  acls, baseacls, name, type);
                              15342                 :                : 
 7625 tgl@sss.pgh.pa.us       15343         [ +  + ]:CBC       22904 :     if (sql->len > 0)
                              15344                 :                :     {
   13 tgl@sss.pgh.pa.us       15345                 :GNC        1971 :         PQExpBuffer tagbuf = createPQExpBuffer();
                              15346                 :                :         DumpId      aclDeps[2];
 1373 tgl@sss.pgh.pa.us       15347                 :CBC        1971 :         int         nDeps = 0;
                              15348                 :                : 
   13 tgl@sss.pgh.pa.us       15349         [ -  + ]:GNC        1971 :         if (tag)
   13 tgl@sss.pgh.pa.us       15350                 :UNC           0 :             appendPQExpBufferStr(tagbuf, tag);
   13 tgl@sss.pgh.pa.us       15351         [ +  + ]:GNC        1971 :         else if (subname)
                              15352                 :           1169 :             appendPQExpBuffer(tagbuf, "COLUMN %s.%s", name, subname);
                              15353                 :                :         else
                              15354                 :            802 :             appendPQExpBuffer(tagbuf, "%s %s", type, name);
                              15355                 :                : 
 1373 tgl@sss.pgh.pa.us       15356                 :CBC        1971 :         aclDeps[nDeps++] = objDumpId;
                              15357         [ +  + ]:           1971 :         if (altDumpId != InvalidDumpId)
                              15358                 :           1092 :             aclDeps[nDeps++] = altDumpId;
                              15359                 :                : 
                              15360                 :           1971 :         aclDumpId = createDumpId();
                              15361                 :                : 
                              15362                 :           1971 :         ArchiveEntry(fout, nilCatalogId, aclDumpId,
   13 tgl@sss.pgh.pa.us       15363                 :GNC        1971 :                      ARCHIVE_OPTS(.tag = tagbuf->data,
                              15364                 :                :                                   .namespace = nspname,
                              15365                 :                :                                   .owner = owner,
                              15366                 :                :                                   .description = "ACL",
                              15367                 :                :                                   .section = SECTION_NONE,
                              15368                 :                :                                   .createStmt = sql->data,
                              15369                 :                :                                   .deps = aclDeps,
                              15370                 :                :                                   .nDeps = nDeps));
                              15371                 :                : 
                              15372                 :           1971 :         destroyPQExpBuffer(tagbuf);
                              15373                 :                :     }
                              15374                 :                : 
 8014 tgl@sss.pgh.pa.us       15375                 :CBC       22904 :     destroyPQExpBuffer(sql);
                              15376                 :                : 
 1373                         15377                 :          22904 :     return aclDumpId;
                              15378                 :                : }
                              15379                 :                : 
                              15380                 :                : /*
                              15381                 :                :  * dumpSecLabel
                              15382                 :                :  *
                              15383                 :                :  * This routine is used to dump any security labels associated with the
                              15384                 :                :  * object handed to this routine. The routine takes the object type
                              15385                 :                :  * and object name (ready to print, except for schema decoration), plus
                              15386                 :                :  * the namespace and owner of the object (for labeling the ArchiveEntry),
                              15387                 :                :  * plus catalog ID and subid which are the lookup key for pg_seclabel,
                              15388                 :                :  * plus the dump ID for the object (for setting a dependency).
                              15389                 :                :  * If a matching pg_seclabel entry is found, it is dumped.
                              15390                 :                :  *
                              15391                 :                :  * Note: although this routine takes a dumpId for dependency purposes,
                              15392                 :                :  * that purpose is just to mark the dependency in the emitted dump file
                              15393                 :                :  * for possible future use by pg_restore.  We do NOT use it for determining
                              15394                 :                :  * ordering of the label in the dump file, because this routine is called
                              15395                 :                :  * after dependency sorting occurs.  This routine should be called just after
                              15396                 :                :  * calling ArchiveEntry() for the specified object.
                              15397                 :                :  */
                              15398                 :                : static void
 2239 tgl@sss.pgh.pa.us       15399                 :UBC           0 : dumpSecLabel(Archive *fout, const char *type, const char *name,
                              15400                 :                :              const char *namespace, const char *owner,
                              15401                 :                :              CatalogId catalogId, int subid, DumpId dumpId)
                              15402                 :                : {
 3014                         15403                 :              0 :     DumpOptions *dopt = fout->dopt;
                              15404                 :                :     SecLabelItem *labels;
                              15405                 :                :     int         nlabels;
                              15406                 :                :     int         i;
                              15407                 :                :     PQExpBuffer query;
                              15408                 :                : 
                              15409                 :                :     /* do nothing, if --no-security-labels is supplied */
 3470 alvherre@alvh.no-ip.    15410         [ #  # ]:              0 :     if (dopt->no_security_labels)
 4948 rhaas@postgresql.org    15411                 :              0 :         return;
                              15412                 :                : 
                              15413                 :                :     /*
                              15414                 :                :      * Security labels are schema not data ... except large object labels are
                              15415                 :                :      * data
                              15416                 :                :      */
 2239 tgl@sss.pgh.pa.us       15417         [ #  # ]:              0 :     if (strcmp(type, "LARGE OBJECT") != 0)
                              15418                 :                :     {
 3470 alvherre@alvh.no-ip.    15419         [ #  # ]:              0 :         if (dopt->dataOnly)
 4948 rhaas@postgresql.org    15420                 :              0 :             return;
                              15421                 :                :     }
                              15422                 :                :     else
                              15423                 :                :     {
                              15424                 :                :         /* We do dump large object security labels in binary-upgrade mode */
 2596 sfrost@snowman.net      15425   [ #  #  #  # ]:              0 :         if (dopt->schemaOnly && !dopt->binary_upgrade)
 4948 rhaas@postgresql.org    15426                 :              0 :             return;
                              15427                 :                :     }
                              15428                 :                : 
                              15429                 :                :     /* Search for security labels associated with catalogId, using table */
  836 tgl@sss.pgh.pa.us       15430                 :              0 :     nlabels = findSecLabels(catalogId.tableoid, catalogId.oid, &labels);
                              15431                 :                : 
 4948 rhaas@postgresql.org    15432                 :              0 :     query = createPQExpBuffer();
                              15433                 :                : 
                              15434         [ #  # ]:              0 :     for (i = 0; i < nlabels; i++)
                              15435                 :                :     {
                              15436                 :                :         /*
                              15437                 :                :          * Ignore label entries for which the subid doesn't match.
                              15438                 :                :          */
                              15439         [ #  # ]:              0 :         if (labels[i].objsubid != subid)
                              15440                 :              0 :             continue;
                              15441                 :                : 
                              15442                 :              0 :         appendPQExpBuffer(query,
                              15443                 :                :                           "SECURITY LABEL FOR %s ON %s ",
 2239 tgl@sss.pgh.pa.us       15444                 :              0 :                           fmtId(labels[i].provider), type);
                              15445   [ #  #  #  # ]:              0 :         if (namespace && *namespace)
                              15446                 :              0 :             appendPQExpBuffer(query, "%s.", fmtId(namespace));
                              15447                 :              0 :         appendPQExpBuffer(query, "%s IS ", name);
 4948 rhaas@postgresql.org    15448                 :              0 :         appendStringLiteralAH(query, labels[i].label, fout);
 3800 heikki.linnakangas@i    15449                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              15450                 :                :     }
                              15451                 :                : 
 4948 rhaas@postgresql.org    15452         [ #  # ]:              0 :     if (query->len > 0)
                              15453                 :                :     {
 2239 tgl@sss.pgh.pa.us       15454                 :              0 :         PQExpBuffer tag = createPQExpBuffer();
                              15455                 :                : 
                              15456                 :              0 :         appendPQExpBuffer(tag, "%s %s", type, name);
 4948 rhaas@postgresql.org    15457                 :              0 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    15458                 :              0 :                      ARCHIVE_OPTS(.tag = tag->data,
                              15459                 :                :                                   .namespace = namespace,
                              15460                 :                :                                   .owner = owner,
                              15461                 :                :                                   .description = "SECURITY LABEL",
                              15462                 :                :                                   .section = SECTION_NONE,
                              15463                 :                :                                   .createStmt = query->data,
                              15464                 :                :                                   .deps = &dumpId,
                              15465                 :                :                                   .nDeps = 1));
 2239 tgl@sss.pgh.pa.us       15466                 :              0 :         destroyPQExpBuffer(tag);
                              15467                 :                :     }
                              15468                 :                : 
 4948 rhaas@postgresql.org    15469                 :              0 :     destroyPQExpBuffer(query);
                              15470                 :                : }
                              15471                 :                : 
                              15472                 :                : /*
                              15473                 :                :  * dumpTableSecLabel
                              15474                 :                :  *
                              15475                 :                :  * As above, but dump security label for both the specified table (or view)
                              15476                 :                :  * and its columns.
                              15477                 :                :  */
                              15478                 :                : static void
 1159 peter@eisentraut.org    15479                 :              0 : dumpTableSecLabel(Archive *fout, const TableInfo *tbinfo, const char *reltypename)
                              15480                 :                : {
 3014 tgl@sss.pgh.pa.us       15481                 :              0 :     DumpOptions *dopt = fout->dopt;
                              15482                 :                :     SecLabelItem *labels;
                              15483                 :                :     int         nlabels;
                              15484                 :                :     int         i;
                              15485                 :                :     PQExpBuffer query;
                              15486                 :                :     PQExpBuffer target;
                              15487                 :                : 
                              15488                 :                :     /* do nothing, if --no-security-labels is supplied */
 3470 alvherre@alvh.no-ip.    15489         [ #  # ]:              0 :     if (dopt->no_security_labels)
 4948 rhaas@postgresql.org    15490                 :              0 :         return;
                              15491                 :                : 
                              15492                 :                :     /* SecLabel are SCHEMA not data */
 3470 alvherre@alvh.no-ip.    15493         [ #  # ]:              0 :     if (dopt->dataOnly)
 4948 rhaas@postgresql.org    15494                 :              0 :         return;
                              15495                 :                : 
                              15496                 :                :     /* Search for comments associated with relation, using table */
  836 tgl@sss.pgh.pa.us       15497                 :              0 :     nlabels = findSecLabels(tbinfo->dobj.catId.tableoid,
 4948 rhaas@postgresql.org    15498                 :              0 :                             tbinfo->dobj.catId.oid,
                              15499                 :                :                             &labels);
                              15500                 :                : 
                              15501                 :                :     /* If security labels exist, build SECURITY LABEL statements */
                              15502         [ #  # ]:              0 :     if (nlabels <= 0)
                              15503                 :              0 :         return;
                              15504                 :                : 
                              15505                 :              0 :     query = createPQExpBuffer();
                              15506                 :              0 :     target = createPQExpBuffer();
                              15507                 :                : 
                              15508         [ #  # ]:              0 :     for (i = 0; i < nlabels; i++)
                              15509                 :                :     {
                              15510                 :                :         const char *colname;
 4753 bruce@momjian.us        15511                 :              0 :         const char *provider = labels[i].provider;
                              15512                 :              0 :         const char *label = labels[i].label;
                              15513                 :              0 :         int         objsubid = labels[i].objsubid;
                              15514                 :                : 
 4948 rhaas@postgresql.org    15515                 :              0 :         resetPQExpBuffer(target);
                              15516         [ #  # ]:              0 :         if (objsubid == 0)
                              15517                 :                :         {
                              15518                 :              0 :             appendPQExpBuffer(target, "%s %s", reltypename,
 2239 tgl@sss.pgh.pa.us       15519                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              15520                 :                :         }
                              15521                 :                :         else
                              15522                 :                :         {
 4948 rhaas@postgresql.org    15523                 :              0 :             colname = getAttrName(objsubid, tbinfo);
                              15524                 :                :             /* first fmtXXX result must be consumed before calling again */
 2239 tgl@sss.pgh.pa.us       15525                 :              0 :             appendPQExpBuffer(target, "COLUMN %s",
                              15526                 :              0 :                               fmtQualifiedDumpable(tbinfo));
 4852 rhaas@postgresql.org    15527                 :              0 :             appendPQExpBuffer(target, ".%s", fmtId(colname));
                              15528                 :                :         }
 4948                         15529                 :              0 :         appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
                              15530                 :                :                           fmtId(provider), target->data);
                              15531                 :              0 :         appendStringLiteralAH(query, label, fout);
 3800 heikki.linnakangas@i    15532                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              15533                 :                :     }
 4948 rhaas@postgresql.org    15534         [ #  # ]:              0 :     if (query->len > 0)
                              15535                 :                :     {
                              15536                 :              0 :         resetPQExpBuffer(target);
                              15537                 :              0 :         appendPQExpBuffer(target, "%s %s", reltypename,
                              15538                 :              0 :                           fmtId(tbinfo->dobj.name));
                              15539                 :              0 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    15540                 :              0 :                      ARCHIVE_OPTS(.tag = target->data,
                              15541                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              15542                 :                :                                   .owner = tbinfo->rolname,
                              15543                 :                :                                   .description = "SECURITY LABEL",
                              15544                 :                :                                   .section = SECTION_NONE,
                              15545                 :                :                                   .createStmt = query->data,
                              15546                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              15547                 :                :                                   .nDeps = 1));
                              15548                 :                :     }
 4948 rhaas@postgresql.org    15549                 :              0 :     destroyPQExpBuffer(query);
                              15550                 :              0 :     destroyPQExpBuffer(target);
                              15551                 :                : }
                              15552                 :                : 
                              15553                 :                : /*
                              15554                 :                :  * findSecLabels
                              15555                 :                :  *
                              15556                 :                :  * Find the security label(s), if any, associated with the given object.
                              15557                 :                :  * All the objsubid values associated with the given classoid/objoid are
                              15558                 :                :  * found with one search.
                              15559                 :                :  */
                              15560                 :                : static int
  836 tgl@sss.pgh.pa.us       15561                 :              0 : findSecLabels(Oid classoid, Oid objoid, SecLabelItem **items)
                              15562                 :                : {
 4753 bruce@momjian.us        15563                 :              0 :     SecLabelItem *middle = NULL;
                              15564                 :                :     SecLabelItem *low;
                              15565                 :                :     SecLabelItem *high;
                              15566                 :                :     int         nmatch;
                              15567                 :                : 
  860 tgl@sss.pgh.pa.us       15568         [ #  # ]:              0 :     if (nseclabels <= 0)     /* no labels, so no match is possible */
                              15569                 :                :     {
 4539                         15570                 :              0 :         *items = NULL;
                              15571                 :              0 :         return 0;
                              15572                 :                :     }
                              15573                 :                : 
                              15574                 :                :     /*
                              15575                 :                :      * Do binary search to find some item matching the object.
                              15576                 :                :      */
  860                         15577                 :              0 :     low = &seclabels[0];
                              15578                 :              0 :     high = &seclabels[nseclabels - 1];
 4948 rhaas@postgresql.org    15579         [ #  # ]:              0 :     while (low <= high)
                              15580                 :                :     {
                              15581                 :              0 :         middle = low + (high - low) / 2;
                              15582                 :                : 
                              15583         [ #  # ]:              0 :         if (classoid < middle->classoid)
                              15584                 :              0 :             high = middle - 1;
                              15585         [ #  # ]:              0 :         else if (classoid > middle->classoid)
                              15586                 :              0 :             low = middle + 1;
                              15587         [ #  # ]:              0 :         else if (objoid < middle->objoid)
                              15588                 :              0 :             high = middle - 1;
                              15589         [ #  # ]:              0 :         else if (objoid > middle->objoid)
                              15590                 :              0 :             low = middle + 1;
                              15591                 :                :         else
 4753 bruce@momjian.us        15592                 :              0 :             break;              /* found a match */
                              15593                 :                :     }
                              15594                 :                : 
                              15595         [ #  # ]:              0 :     if (low > high)              /* no matches */
                              15596                 :                :     {
 4948 rhaas@postgresql.org    15597                 :              0 :         *items = NULL;
                              15598                 :              0 :         return 0;
                              15599                 :                :     }
                              15600                 :                : 
                              15601                 :                :     /*
                              15602                 :                :      * Now determine how many items match the object.  The search loop
                              15603                 :                :      * invariant still holds: only items between low and high inclusive could
                              15604                 :                :      * match.
                              15605                 :                :      */
                              15606                 :              0 :     nmatch = 1;
                              15607         [ #  # ]:              0 :     while (middle > low)
                              15608                 :                :     {
                              15609         [ #  # ]:              0 :         if (classoid != middle[-1].classoid ||
                              15610         [ #  # ]:              0 :             objoid != middle[-1].objoid)
                              15611                 :                :             break;
                              15612                 :              0 :         middle--;
                              15613                 :              0 :         nmatch++;
                              15614                 :                :     }
                              15615                 :                : 
                              15616                 :              0 :     *items = middle;
                              15617                 :                : 
                              15618                 :              0 :     middle += nmatch;
                              15619         [ #  # ]:              0 :     while (middle <= high)
                              15620                 :                :     {
                              15621         [ #  # ]:              0 :         if (classoid != middle->classoid ||
                              15622         [ #  # ]:              0 :             objoid != middle->objoid)
                              15623                 :                :             break;
                              15624                 :              0 :         middle++;
                              15625                 :              0 :         nmatch++;
                              15626                 :                :     }
                              15627                 :                : 
                              15628                 :              0 :     return nmatch;
                              15629                 :                : }
                              15630                 :                : 
                              15631                 :                : /*
                              15632                 :                :  * collectSecLabels
                              15633                 :                :  *
                              15634                 :                :  * Construct a table of all security labels available for database objects;
                              15635                 :                :  * also set the has-seclabel component flag for each relevant object.
                              15636                 :                :  *
                              15637                 :                :  * The table is sorted by classoid/objid/objsubid for speed in lookup.
                              15638                 :                :  */
                              15639                 :                : static void
  860 tgl@sss.pgh.pa.us       15640                 :CBC         155 : collectSecLabels(Archive *fout)
                              15641                 :                : {
                              15642                 :                :     PGresult   *res;
                              15643                 :                :     PQExpBuffer query;
                              15644                 :                :     int         i_label;
                              15645                 :                :     int         i_provider;
                              15646                 :                :     int         i_classoid;
                              15647                 :                :     int         i_objoid;
                              15648                 :                :     int         i_objsubid;
                              15649                 :                :     int         ntups;
                              15650                 :                :     int         i;
                              15651                 :                :     DumpableObject *dobj;
                              15652                 :                : 
 4948 rhaas@postgresql.org    15653                 :            155 :     query = createPQExpBuffer();
                              15654                 :                : 
 3800 heikki.linnakangas@i    15655                 :            155 :     appendPQExpBufferStr(query,
                              15656                 :                :                          "SELECT label, provider, classoid, objoid, objsubid "
                              15657                 :                :                          "FROM pg_catalog.pg_seclabel "
                              15658                 :                :                          "ORDER BY classoid, objoid, objsubid");
                              15659                 :                : 
 4450 rhaas@postgresql.org    15660                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              15661                 :                : 
                              15662                 :                :     /* Construct lookup table containing OIDs in numeric form */
 4753 bruce@momjian.us        15663                 :            155 :     i_label = PQfnumber(res, "label");
                              15664                 :            155 :     i_provider = PQfnumber(res, "provider");
                              15665                 :            155 :     i_classoid = PQfnumber(res, "classoid");
                              15666                 :            155 :     i_objoid = PQfnumber(res, "objoid");
                              15667                 :            155 :     i_objsubid = PQfnumber(res, "objsubid");
                              15668                 :                : 
 4948 rhaas@postgresql.org    15669                 :            155 :     ntups = PQntuples(res);
                              15670                 :                : 
  860 tgl@sss.pgh.pa.us       15671                 :            155 :     seclabels = (SecLabelItem *) pg_malloc(ntups * sizeof(SecLabelItem));
                              15672                 :            155 :     nseclabels = 0;
                              15673                 :            155 :     dobj = NULL;
                              15674                 :                : 
 4948 rhaas@postgresql.org    15675         [ -  + ]:            155 :     for (i = 0; i < ntups; i++)
                              15676                 :                :     {
                              15677                 :                :         CatalogId   objId;
                              15678                 :                :         int         subid;
                              15679                 :                : 
  860 tgl@sss.pgh.pa.us       15680                 :UBC           0 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classoid));
                              15681                 :              0 :         objId.oid = atooid(PQgetvalue(res, i, i_objoid));
                              15682                 :              0 :         subid = atoi(PQgetvalue(res, i, i_objsubid));
                              15683                 :                : 
                              15684                 :                :         /* We needn't remember labels that don't match any dumpable object */
                              15685         [ #  # ]:              0 :         if (dobj == NULL ||
                              15686         [ #  # ]:              0 :             dobj->catId.tableoid != objId.tableoid ||
                              15687         [ #  # ]:              0 :             dobj->catId.oid != objId.oid)
                              15688                 :              0 :             dobj = findObjectByCatalogId(objId);
                              15689         [ #  # ]:              0 :         if (dobj == NULL)
                              15690                 :              0 :             continue;
                              15691                 :                : 
                              15692                 :                :         /*
                              15693                 :                :          * Labels on columns of composite types are linked to the type's
                              15694                 :                :          * pg_class entry, but we need to set the DUMP_COMPONENT_SECLABEL flag
                              15695                 :                :          * in the type's own DumpableObject.
                              15696                 :                :          */
                              15697   [ #  #  #  # ]:              0 :         if (subid != 0 && dobj->objType == DO_TABLE &&
                              15698         [ #  # ]:              0 :             ((TableInfo *) dobj)->relkind == RELKIND_COMPOSITE_TYPE)
                              15699                 :              0 :         {
                              15700                 :                :             TypeInfo   *cTypeInfo;
                              15701                 :                : 
                              15702                 :              0 :             cTypeInfo = findTypeByOid(((TableInfo *) dobj)->reltype);
                              15703         [ #  # ]:              0 :             if (cTypeInfo)
                              15704                 :              0 :                 cTypeInfo->dobj.components |= DUMP_COMPONENT_SECLABEL;
                              15705                 :                :         }
                              15706                 :                :         else
                              15707                 :              0 :             dobj->components |= DUMP_COMPONENT_SECLABEL;
                              15708                 :                : 
                              15709                 :              0 :         seclabels[nseclabels].label = pg_strdup(PQgetvalue(res, i, i_label));
                              15710                 :              0 :         seclabels[nseclabels].provider = pg_strdup(PQgetvalue(res, i, i_provider));
                              15711                 :              0 :         seclabels[nseclabels].classoid = objId.tableoid;
                              15712                 :              0 :         seclabels[nseclabels].objoid = objId.oid;
                              15713                 :              0 :         seclabels[nseclabels].objsubid = subid;
                              15714                 :              0 :         nseclabels++;
                              15715                 :                :     }
                              15716                 :                : 
  860 tgl@sss.pgh.pa.us       15717                 :CBC         155 :     PQclear(res);
 4753 bruce@momjian.us        15718                 :            155 :     destroyPQExpBuffer(query);
 4948 rhaas@postgresql.org    15719                 :            155 : }
                              15720                 :                : 
                              15721                 :                : /*
                              15722                 :                :  * dumpTable
                              15723                 :                :  *    write out to fout the declarations (not data) of a user-defined table
                              15724                 :                :  */
                              15725                 :                : static void
 1159 peter@eisentraut.org    15726                 :          25269 : dumpTable(Archive *fout, const TableInfo *tbinfo)
                              15727                 :                : {
 2930 sfrost@snowman.net      15728                 :          25269 :     DumpOptions *dopt = fout->dopt;
 1373 tgl@sss.pgh.pa.us       15729                 :          25269 :     DumpId      tableAclDumpId = InvalidDumpId;
                              15730                 :                :     char       *namecopy;
                              15731                 :                : 
                              15732                 :                :     /* Do nothing in data-only dump */
  860                         15733         [ +  + ]:          25269 :     if (dopt->dataOnly)
 2928 sfrost@snowman.net      15734                 :            867 :         return;
                              15735                 :                : 
  860 tgl@sss.pgh.pa.us       15736         [ +  + ]:          24402 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              15737                 :                :     {
                              15738         [ +  + ]:           5789 :         if (tbinfo->relkind == RELKIND_SEQUENCE)
                              15739                 :            367 :             dumpSequence(fout, tbinfo);
                              15740                 :                :         else
                              15741                 :           5422 :             dumpTableSchema(fout, tbinfo);
                              15742                 :                :     }
                              15743                 :                : 
                              15744                 :                :     /* Handle the ACL here */
 2930 sfrost@snowman.net      15745                 :          24402 :     namecopy = pg_strdup(fmtId(tbinfo->dobj.name));
                              15746         [ +  + ]:          24402 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_ACL)
                              15747                 :                :     {
 2274 tgl@sss.pgh.pa.us       15748                 :          19066 :         const char *objtype =
  331                         15749         [ +  + ]:          19066 :             (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
                              15750                 :                : 
                              15751                 :                :         tableAclDumpId =
 1373                         15752                 :          19066 :             dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
                              15753                 :                :                     objtype, namecopy, NULL,
   13 tgl@sss.pgh.pa.us       15754                 :GNC       19066 :                     tbinfo->dobj.namespace->dobj.name,
                              15755                 :          19066 :                     NULL, tbinfo->rolname, &tbinfo->dacl);
                              15756                 :                :     }
                              15757                 :                : 
                              15758                 :                :     /*
                              15759                 :                :      * Handle column ACLs, if any.  Note: we pull these with a separate query
                              15760                 :                :      * rather than trying to fetch them during getTableAttrs, so that we won't
                              15761                 :                :      * miss ACLs on system columns.  Doing it this way also allows us to dump
                              15762                 :                :      * ACLs for catalogs that we didn't mark "interesting" back in getTables.
                              15763                 :                :      */
  860 tgl@sss.pgh.pa.us       15764   [ +  +  +  + ]:CBC       24402 :     if ((tbinfo->dobj.dump & DUMP_COMPONENT_ACL) && tbinfo->hascolumnACLs)
                              15765                 :                :     {
 2930 sfrost@snowman.net      15766                 :            261 :         PQExpBuffer query = createPQExpBuffer();
                              15767                 :                :         PGresult   *res;
                              15768                 :                :         int         i;
                              15769                 :                : 
  860 tgl@sss.pgh.pa.us       15770         [ +  + ]:            261 :         if (!fout->is_prepared[PREPQUERY_GETCOLUMNACLS])
                              15771                 :                :         {
                              15772                 :                :             /* Set up query for column ACLs */
                              15773                 :            132 :             appendPQExpBufferStr(query,
                              15774                 :                :                                  "PREPARE getColumnACLs(pg_catalog.oid) AS\n");
                              15775                 :                : 
                              15776         [ +  - ]:            132 :             if (fout->remoteVersion >= 90600)
                              15777                 :                :             {
                              15778                 :                :                 /*
                              15779                 :                :                  * In principle we should call acldefault('c', relowner) to
                              15780                 :                :                  * get the default ACL for a column.  However, we don't
                              15781                 :                :                  * currently store the numeric OID of the relowner in
                              15782                 :                :                  * TableInfo.  We could convert the owner name using regrole,
                              15783                 :                :                  * but that creates a risk of failure due to concurrent role
                              15784                 :                :                  * renames.  Given that the default ACL for columns is empty
                              15785                 :                :                  * and is likely to stay that way, it's not worth extra cycles
                              15786                 :                :                  * and risk to avoid hard-wiring that knowledge here.
                              15787                 :                :                  */
                              15788                 :            132 :                 appendPQExpBufferStr(query,
                              15789                 :                :                                      "SELECT at.attname, "
                              15790                 :                :                                      "at.attacl, "
                              15791                 :                :                                      "'{}' AS acldefault, "
                              15792                 :                :                                      "pip.privtype, pip.initprivs "
                              15793                 :                :                                      "FROM pg_catalog.pg_attribute at "
                              15794                 :                :                                      "LEFT JOIN pg_catalog.pg_init_privs pip ON "
                              15795                 :                :                                      "(at.attrelid = pip.objoid "
                              15796                 :                :                                      "AND pip.classoid = 'pg_catalog.pg_class'::pg_catalog.regclass "
                              15797                 :                :                                      "AND at.attnum = pip.objsubid) "
                              15798                 :                :                                      "WHERE at.attrelid = $1 AND "
                              15799                 :                :                                      "NOT at.attisdropped "
                              15800                 :                :                                      "AND (at.attacl IS NOT NULL OR pip.initprivs IS NOT NULL) "
                              15801                 :                :                                      "ORDER BY at.attnum");
                              15802                 :                :             }
                              15803                 :                :             else
                              15804                 :                :             {
  860 tgl@sss.pgh.pa.us       15805                 :UBC           0 :                 appendPQExpBufferStr(query,
                              15806                 :                :                                      "SELECT attname, attacl, '{}' AS acldefault, "
                              15807                 :                :                                      "NULL AS privtype, NULL AS initprivs "
                              15808                 :                :                                      "FROM pg_catalog.pg_attribute "
                              15809                 :                :                                      "WHERE attrelid = $1 AND NOT attisdropped "
                              15810                 :                :                                      "AND attacl IS NOT NULL "
                              15811                 :                :                                      "ORDER BY attnum");
                              15812                 :                :             }
                              15813                 :                : 
  860 tgl@sss.pgh.pa.us       15814                 :CBC         132 :             ExecuteSqlStatement(fout, query->data);
                              15815                 :                : 
                              15816                 :            132 :             fout->is_prepared[PREPQUERY_GETCOLUMNACLS] = true;
                              15817                 :                :         }
                              15818                 :                : 
                              15819                 :            261 :         printfPQExpBuffer(query,
                              15820                 :                :                           "EXECUTE getColumnACLs('%u')",
                              15821                 :            261 :                           tbinfo->dobj.catId.oid);
                              15822                 :                : 
 2930 sfrost@snowman.net      15823                 :            261 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              15824                 :                : 
                              15825         [ +  + ]:           3623 :         for (i = 0; i < PQntuples(res); i++)
                              15826                 :                :         {
                              15827                 :           3362 :             char       *attname = PQgetvalue(res, i, 0);
                              15828                 :           3362 :             char       *attacl = PQgetvalue(res, i, 1);
  860 tgl@sss.pgh.pa.us       15829                 :           3362 :             char       *acldefault = PQgetvalue(res, i, 2);
                              15830                 :           3362 :             char        privtype = *(PQgetvalue(res, i, 3));
                              15831                 :           3362 :             char       *initprivs = PQgetvalue(res, i, 4);
                              15832                 :                :             DumpableAcl coldacl;
                              15833                 :                :             char       *attnamecopy;
                              15834                 :                : 
                              15835                 :           3362 :             coldacl.acl = attacl;
                              15836                 :           3362 :             coldacl.acldefault = acldefault;
                              15837                 :           3362 :             coldacl.privtype = privtype;
                              15838                 :           3362 :             coldacl.initprivs = initprivs;
 2930 sfrost@snowman.net      15839                 :           3362 :             attnamecopy = pg_strdup(fmtId(attname));
                              15840                 :                : 
                              15841                 :                :             /*
                              15842                 :                :              * Column's GRANT type is always TABLE.  Each column ACL depends
                              15843                 :                :              * on the table-level ACL, since we can restore column ACLs in
                              15844                 :                :              * parallel but the table-level ACL has to be done first.
                              15845                 :                :              */
 1373 tgl@sss.pgh.pa.us       15846                 :           3362 :             dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
                              15847                 :                :                     "TABLE", namecopy, attnamecopy,
   13 tgl@sss.pgh.pa.us       15848                 :GNC        3362 :                     tbinfo->dobj.namespace->dobj.name,
                              15849                 :           3362 :                     NULL, tbinfo->rolname, &coldacl);
 2930 sfrost@snowman.net      15850                 :CBC        3362 :             free(attnamecopy);
                              15851                 :                :         }
                              15852                 :            261 :         PQclear(res);
                              15853                 :            261 :         destroyPQExpBuffer(query);
                              15854                 :                :     }
                              15855                 :                : 
                              15856                 :          24402 :     free(namecopy);
                              15857                 :                : }
                              15858                 :                : 
                              15859                 :                : /*
                              15860                 :                :  * Create the AS clause for a view or materialized view. The semicolon is
                              15861                 :                :  * stripped because a materialized view must add a WITH NO DATA clause.
                              15862                 :                :  *
                              15863                 :                :  * This returns a new buffer which must be freed by the caller.
                              15864                 :                :  */
                              15865                 :                : static PQExpBuffer
 1159 peter@eisentraut.org    15866                 :            713 : createViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              15867                 :                : {
 4060 kgrittn@postgresql.o    15868                 :            713 :     PQExpBuffer query = createPQExpBuffer();
                              15869                 :            713 :     PQExpBuffer result = createPQExpBuffer();
                              15870                 :                :     PGresult   *res;
                              15871                 :                :     int         len;
                              15872                 :                : 
                              15873                 :                :     /* Fetch the view definition */
 2741 tgl@sss.pgh.pa.us       15874                 :            713 :     appendPQExpBuffer(query,
                              15875                 :                :                       "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
                              15876                 :            713 :                       tbinfo->dobj.catId.oid);
                              15877                 :                : 
 4060 kgrittn@postgresql.o    15878                 :            713 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              15879                 :                : 
                              15880         [ -  + ]:            713 :     if (PQntuples(res) != 1)
                              15881                 :                :     {
 4060 kgrittn@postgresql.o    15882         [ #  # ]:UBC           0 :         if (PQntuples(res) < 1)
  737 tgl@sss.pgh.pa.us       15883                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned no data",
                              15884                 :                :                      tbinfo->dobj.name);
                              15885                 :                :         else
                              15886                 :              0 :             pg_fatal("query to obtain definition of view \"%s\" returned more than one definition",
                              15887                 :                :                      tbinfo->dobj.name);
                              15888                 :                :     }
                              15889                 :                : 
 4060 kgrittn@postgresql.o    15890                 :CBC         713 :     len = PQgetlength(res, 0, 0);
                              15891                 :                : 
                              15892         [ -  + ]:            713 :     if (len == 0)
  737 tgl@sss.pgh.pa.us       15893                 :UBC           0 :         pg_fatal("definition of view \"%s\" appears to be empty (length zero)",
                              15894                 :                :                  tbinfo->dobj.name);
                              15895                 :                : 
                              15896                 :                :     /* Strip off the trailing semicolon so that other things may follow. */
 4039 andrew@dunslane.net     15897         [ -  + ]:CBC         713 :     Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
 4060 kgrittn@postgresql.o    15898                 :            713 :     appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
                              15899                 :                : 
                              15900                 :            713 :     PQclear(res);
                              15901                 :            713 :     destroyPQExpBuffer(query);
                              15902                 :                : 
                              15903                 :            713 :     return result;
                              15904                 :                : }
                              15905                 :                : 
                              15906                 :                : /*
                              15907                 :                :  * Create a dummy AS clause for a view.  This is used when the real view
                              15908                 :                :  * definition has to be postponed because of circular dependencies.
                              15909                 :                :  * We must duplicate the view's external properties -- column names and types
                              15910                 :                :  * (including collation) -- so that it works for subsequent references.
                              15911                 :                :  *
                              15912                 :                :  * This returns a new buffer which must be freed by the caller.
                              15913                 :                :  */
                              15914                 :                : static PQExpBuffer
 1159 peter@eisentraut.org    15915                 :             20 : createDummyViewAsClause(Archive *fout, const TableInfo *tbinfo)
                              15916                 :                : {
 2705 tgl@sss.pgh.pa.us       15917                 :             20 :     PQExpBuffer result = createPQExpBuffer();
                              15918                 :                :     int         j;
                              15919                 :                : 
                              15920                 :             20 :     appendPQExpBufferStr(result, "SELECT");
                              15921                 :                : 
                              15922         [ +  + ]:             40 :     for (j = 0; j < tbinfo->numatts; j++)
                              15923                 :                :     {
                              15924         [ +  + ]:             20 :         if (j > 0)
                              15925                 :             10 :             appendPQExpBufferChar(result, ',');
                              15926                 :             20 :         appendPQExpBufferStr(result, "\n    ");
                              15927                 :                : 
                              15928                 :             20 :         appendPQExpBuffer(result, "NULL::%s", tbinfo->atttypnames[j]);
                              15929                 :                : 
                              15930                 :                :         /*
                              15931                 :                :          * Must add collation if not default for the type, because CREATE OR
                              15932                 :                :          * REPLACE VIEW won't change it
                              15933                 :                :          */
                              15934         [ -  + ]:             20 :         if (OidIsValid(tbinfo->attcollation[j]))
                              15935                 :                :         {
                              15936                 :                :             CollInfo   *coll;
                              15937                 :                : 
 2705 tgl@sss.pgh.pa.us       15938                 :UBC           0 :             coll = findCollationByOid(tbinfo->attcollation[j]);
                              15939         [ #  # ]:              0 :             if (coll)
 2239                         15940                 :              0 :                 appendPQExpBuffer(result, " COLLATE %s",
                              15941                 :              0 :                                   fmtQualifiedDumpable(coll));
                              15942                 :                :         }
                              15943                 :                : 
 2705 tgl@sss.pgh.pa.us       15944                 :CBC          20 :         appendPQExpBuffer(result, " AS %s", fmtId(tbinfo->attnames[j]));
                              15945                 :                :     }
                              15946                 :                : 
                              15947                 :             20 :     return result;
                              15948                 :                : }
                              15949                 :                : 
                              15950                 :                : /*
                              15951                 :                :  * dumpTableSchema
                              15952                 :                :  *    write the declaration (not data) of one user-defined table or view
                              15953                 :                :  */
                              15954                 :                : static void
 1159 peter@eisentraut.org    15955                 :           5422 : dumpTableSchema(Archive *fout, const TableInfo *tbinfo)
                              15956                 :                : {
 3014 tgl@sss.pgh.pa.us       15957                 :           5422 :     DumpOptions *dopt = fout->dopt;
 8768 bruce@momjian.us        15958                 :           5422 :     PQExpBuffer q = createPQExpBuffer();
 8685                         15959                 :           5422 :     PQExpBuffer delq = createPQExpBuffer();
                              15960                 :                :     char       *qrelname;
                              15961                 :                :     char       *qualrelname;
                              15962                 :                :     int         numParents;
                              15963                 :                :     TableInfo **parents;
                              15964                 :                :     int         actual_atts;    /* number of attrs in this CREATE statement */
                              15965                 :                :     const char *reltypename;
                              15966                 :                :     char       *storage;
                              15967                 :                :     int         j,
                              15968                 :                :                 k;
                              15969                 :                : 
                              15970                 :                :     /* We had better have loaded per-column details about this table */
 1285 tgl@sss.pgh.pa.us       15971         [ -  + ]:           5422 :     Assert(tbinfo->interesting);
                              15972                 :                : 
 2239                         15973                 :           5422 :     qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
                              15974                 :           5422 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              15975                 :                : 
 1972 andres@anarazel.de      15976         [ -  + ]:           5422 :     if (tbinfo->hasoids)
 1840 peter@eisentraut.org    15977                 :UBC           0 :         pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")",
                              15978                 :                :                        qrelname);
                              15979                 :                : 
 3470 alvherre@alvh.no-ip.    15980         [ +  + ]:CBC        5422 :     if (dopt->binary_upgrade)
  860 tgl@sss.pgh.pa.us       15981                 :            760 :         binary_upgrade_set_type_oids_by_rel(fout, q, tbinfo);
                              15982                 :                : 
                              15983                 :                :     /* Is it a table or a view? */
 8010                         15984         [ +  + ]:           5422 :     if (tbinfo->relkind == RELKIND_VIEW)
                              15985                 :                :     {
                              15986                 :                :         PQExpBuffer result;
                              15987                 :                : 
                              15988                 :                :         /*
                              15989                 :                :          * Note: keep this code in sync with the is_view case in dumpRule()
                              15990                 :                :          */
                              15991                 :                : 
                              15992                 :            349 :         reltypename = "VIEW";
                              15993                 :                : 
 2239                         15994                 :            349 :         appendPQExpBuffer(delq, "DROP VIEW %s;\n", qualrelname);
                              15995                 :                : 
 3470 alvherre@alvh.no-ip.    15996         [ +  + ]:            349 :         if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    15997                 :             48 :             binary_upgrade_set_pg_class_oids(fout, q,
                              15998                 :             48 :                                              tbinfo->dobj.catId.oid, false);
                              15999                 :                : 
 2239 tgl@sss.pgh.pa.us       16000                 :            349 :         appendPQExpBuffer(q, "CREATE VIEW %s", qualrelname);
                              16001                 :                : 
 2705                         16002         [ +  + ]:            349 :         if (tbinfo->dummy_view)
                              16003                 :             10 :             result = createDummyViewAsClause(fout, tbinfo);
                              16004                 :                :         else
                              16005                 :                :         {
                              16006         [ +  + ]:            339 :             if (nonemptyReloptions(tbinfo->reloptions))
                              16007                 :                :             {
                              16008                 :             59 :                 appendPQExpBufferStr(q, " WITH (");
                              16009                 :             59 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              16010                 :             59 :                 appendPQExpBufferChar(q, ')');
                              16011                 :                :             }
                              16012                 :            339 :             result = createViewAsClause(fout, tbinfo);
                              16013                 :                :         }
 3923 sfrost@snowman.net      16014                 :            349 :         appendPQExpBuffer(q, " AS\n%s", result->data);
 4060 kgrittn@postgresql.o    16015                 :            349 :         destroyPQExpBuffer(result);
                              16016                 :                : 
 2705 tgl@sss.pgh.pa.us       16017   [ +  +  +  - ]:            349 :         if (tbinfo->checkoption != NULL && !tbinfo->dummy_view)
 3923 sfrost@snowman.net      16018                 :             36 :             appendPQExpBuffer(q, "\n  WITH %s CHECK OPTION", tbinfo->checkoption);
 3800 heikki.linnakangas@i    16019                 :            349 :         appendPQExpBufferStr(q, ";\n");
                              16020                 :                :     }
                              16021                 :                :     else
                              16022                 :                :     {
  860 tgl@sss.pgh.pa.us       16023                 :           5073 :         char       *partkeydef = NULL;
 1956 sfrost@snowman.net      16024                 :           5073 :         char       *ftoptions = NULL;
                              16025                 :           5073 :         char       *srvname = NULL;
 1486 alvherre@alvh.no-ip.    16026                 :           5073 :         char       *foreign = "";
                              16027                 :                : 
                              16028                 :                :         /*
                              16029                 :                :          * Set reltypename, and collect any relkind-specific data that we
                              16030                 :                :          * didn't fetch during getTables().
                              16031                 :                :          */
 4060 kgrittn@postgresql.o    16032   [ +  +  +  + ]:           5073 :         switch (tbinfo->relkind)
                              16033                 :                :         {
  860 tgl@sss.pgh.pa.us       16034                 :            512 :             case RELKIND_PARTITIONED_TABLE:
                              16035                 :                :                 {
                              16036                 :            512 :                     PQExpBuffer query = createPQExpBuffer();
                              16037                 :                :                     PGresult   *res;
                              16038                 :                : 
                              16039                 :            512 :                     reltypename = "TABLE";
                              16040                 :                : 
                              16041                 :                :                     /* retrieve partition key definition */
                              16042                 :            512 :                     appendPQExpBuffer(query,
                              16043                 :                :                                       "SELECT pg_get_partkeydef('%u')",
                              16044                 :            512 :                                       tbinfo->dobj.catId.oid);
                              16045                 :            512 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              16046                 :            512 :                     partkeydef = pg_strdup(PQgetvalue(res, 0, 0));
                              16047                 :            512 :                     PQclear(res);
                              16048                 :            512 :                     destroyPQExpBuffer(query);
                              16049                 :            512 :                     break;
                              16050                 :                :                 }
 2593                         16051                 :             38 :             case RELKIND_FOREIGN_TABLE:
                              16052                 :                :                 {
 4039 andrew@dunslane.net     16053                 :             38 :                     PQExpBuffer query = createPQExpBuffer();
                              16054                 :                :                     PGresult   *res;
                              16055                 :                :                     int         i_srvname;
                              16056                 :                :                     int         i_ftoptions;
                              16057                 :                : 
                              16058                 :             38 :                     reltypename = "FOREIGN TABLE";
                              16059                 :                : 
                              16060                 :                :                     /* retrieve name of foreign server and generic options */
                              16061                 :             38 :                     appendPQExpBuffer(query,
                              16062                 :                :                                       "SELECT fs.srvname, "
                              16063                 :                :                                       "pg_catalog.array_to_string(ARRAY("
                              16064                 :                :                                       "SELECT pg_catalog.quote_ident(option_name) || "
                              16065                 :                :                                       "' ' || pg_catalog.quote_literal(option_value) "
                              16066                 :                :                                       "FROM pg_catalog.pg_options_to_table(ftoptions) "
                              16067                 :                :                                       "ORDER BY option_name"
                              16068                 :                :                                       "), E',\n    ') AS ftoptions "
                              16069                 :                :                                       "FROM pg_catalog.pg_foreign_table ft "
                              16070                 :                :                                       "JOIN pg_catalog.pg_foreign_server fs "
                              16071                 :                :                                       "ON (fs.oid = ft.ftserver) "
                              16072                 :                :                                       "WHERE ft.ftrelid = '%u'",
                              16073                 :             38 :                                       tbinfo->dobj.catId.oid);
                              16074                 :             38 :                     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              16075                 :             38 :                     i_srvname = PQfnumber(res, "srvname");
                              16076                 :             38 :                     i_ftoptions = PQfnumber(res, "ftoptions");
                              16077                 :             38 :                     srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
                              16078                 :             38 :                     ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
                              16079                 :             38 :                     PQclear(res);
                              16080                 :             38 :                     destroyPQExpBuffer(query);
                              16081                 :                : 
 1486 alvherre@alvh.no-ip.    16082                 :             38 :                     foreign = "FOREIGN ";
 4039 andrew@dunslane.net     16083                 :             38 :                     break;
                              16084                 :                :                 }
 2593 tgl@sss.pgh.pa.us       16085                 :            364 :             case RELKIND_MATVIEW:
 4060 kgrittn@postgresql.o    16086                 :            364 :                 reltypename = "MATERIALIZED VIEW";
                              16087                 :            364 :                 break;
                              16088                 :           4159 :             default:
                              16089                 :           4159 :                 reltypename = "TABLE";
  860 tgl@sss.pgh.pa.us       16090                 :           4159 :                 break;
                              16091                 :                :         }
                              16092                 :                : 
 8010                         16093                 :           5073 :         numParents = tbinfo->numParents;
 7435                         16094                 :           5073 :         parents = tbinfo->parents;
                              16095                 :                : 
 2239                         16096                 :           5073 :         appendPQExpBuffer(delq, "DROP %s %s;\n", reltypename, qualrelname);
                              16097                 :                : 
 3470 alvherre@alvh.no-ip.    16098         [ +  + ]:           5073 :         if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    16099                 :            712 :             binary_upgrade_set_pg_class_oids(fout, q,
                              16100                 :            712 :                                              tbinfo->dobj.catId.oid, false);
                              16101                 :                : 
 4852                         16102                 :           5073 :         appendPQExpBuffer(q, "CREATE %s%s %s",
                              16103         [ +  + ]:           5073 :                           tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              16104                 :                :                           "UNLOGGED " : "",
                              16105                 :                :                           reltypename,
                              16106                 :                :                           qualrelname);
                              16107                 :                : 
                              16108                 :                :         /*
                              16109                 :                :          * Attach to type, if reloftype; except in case of a binary upgrade,
                              16110                 :                :          * we dump the table normally and attach it to the type afterward.
                              16111                 :                :          */
  860 tgl@sss.pgh.pa.us       16112   [ +  +  +  + ]:           5073 :         if (OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade)
                              16113                 :             24 :             appendPQExpBuffer(q, " OF %s",
                              16114                 :             24 :                               getFormattedTypeName(fout, tbinfo->reloftype,
                              16115                 :                :                                                    zeroIsError));
                              16116                 :                : 
 4060 kgrittn@postgresql.o    16117         [ +  + ]:           5073 :         if (tbinfo->relkind != RELKIND_MATVIEW)
                              16118                 :                :         {
                              16119                 :                :             /* Dump the attributes */
 4039 andrew@dunslane.net     16120                 :           4709 :             actual_atts = 0;
                              16121         [ +  + ]:          22400 :             for (j = 0; j < tbinfo->numatts; j++)
                              16122                 :                :             {
                              16123                 :                :                 /*
                              16124                 :                :                  * Normally, dump if it's locally defined in this table, and
                              16125                 :                :                  * not dropped.  But for binary upgrade, we'll dump all the
                              16126                 :                :                  * columns, and then fix up the dropped and nonlocal cases
                              16127                 :                :                  * below.
                              16128                 :                :                  */
 3470 alvherre@alvh.no-ip.    16129         [ +  + ]:          17691 :                 if (shouldPrintColumn(dopt, tbinfo, j))
                              16130                 :                :                 {
                              16131                 :                :                     bool        print_default;
                              16132                 :                :                     bool        print_notnull;
                              16133                 :                : 
                              16134                 :                :                     /*
                              16135                 :                :                      * Default value --- suppress if to be printed separately
                              16136                 :                :                      * or not at all.
                              16137                 :                :                      */
 1770                         16138                 :          34565 :                     print_default = (tbinfo->attrdefs[j] != NULL &&
  411 tgl@sss.pgh.pa.us       16139   [ +  +  +  + ]:          17650 :                                      tbinfo->attrdefs[j]->dobj.dump &&
 1770 alvherre@alvh.no-ip.    16140         [ +  + ]:            778 :                                      !tbinfo->attrdefs[j]->separate);
                              16141                 :                : 
                              16142                 :                :                     /*
                              16143                 :                :                      * Not Null constraint --- suppress unless it is locally
                              16144                 :                :                      * defined, except if partition, or in binary-upgrade case
                              16145                 :                :                      * where that won't work.
                              16146                 :                :                      */
  233 alvherre@alvh.no-ip.    16147                 :GNC       16872 :                     print_notnull =
                              16148         [ +  + ]:          18728 :                         (tbinfo->notnull_constrs[j] != NULL &&
                              16149   [ +  +  +  + ]:           1856 :                          (!tbinfo->notnull_inh[j] || tbinfo->ispartition ||
                              16150         [ +  + ]:             51 :                           dopt->binary_upgrade));
                              16151                 :                : 
                              16152                 :                :                     /*
                              16153                 :                :                      * Skip column if fully defined by reloftype, except in
                              16154                 :                :                      * binary upgrade
                              16155                 :                :                      */
  860 tgl@sss.pgh.pa.us       16156         [ +  + ]:CBC       16872 :                     if (OidIsValid(tbinfo->reloftype) &&
                              16157   [ +  +  +  + ]:             50 :                         !print_default && !print_notnull &&
 1770 alvherre@alvh.no-ip.    16158         [ +  + ]:             30 :                         !dopt->binary_upgrade)
 4039 andrew@dunslane.net     16159                 :             24 :                         continue;
                              16160                 :                : 
                              16161                 :                :                     /* Format properly if not first attr */
                              16162         [ +  + ]:          16848 :                     if (actual_atts == 0)
 3800 heikki.linnakangas@i    16163                 :           4454 :                         appendPQExpBufferStr(q, " (");
                              16164                 :                :                     else
 3209                         16165                 :          12394 :                         appendPQExpBufferChar(q, ',');
 3800                         16166                 :          16848 :                     appendPQExpBufferStr(q, "\n    ");
 4039 andrew@dunslane.net     16167                 :          16848 :                     actual_atts++;
                              16168                 :                : 
                              16169                 :                :                     /* Attribute name */
 3800 heikki.linnakangas@i    16170                 :          16848 :                     appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
                              16171                 :                : 
 4039 andrew@dunslane.net     16172         [ +  + ]:          16848 :                     if (tbinfo->attisdropped[j])
                              16173                 :                :                     {
                              16174                 :                :                         /*
                              16175                 :                :                          * ALTER TABLE DROP COLUMN clears
                              16176                 :                :                          * pg_attribute.atttypid, so we will not have gotten a
                              16177                 :                :                          * valid type name; insert INTEGER as a stopgap. We'll
                              16178                 :                :                          * clean things up later.
                              16179                 :                :                          */
 3800 heikki.linnakangas@i    16180                 :             79 :                         appendPQExpBufferStr(q, " INTEGER /* dummy */");
                              16181                 :                :                         /* and skip to the next column */
 4039 andrew@dunslane.net     16182                 :             79 :                         continue;
                              16183                 :                :                     }
                              16184                 :                : 
                              16185                 :                :                     /*
                              16186                 :                :                      * Attribute type; print it except when creating a typed
                              16187                 :                :                      * table ('OF type_name'), but in binary-upgrade mode,
                              16188                 :                :                      * print it in that case too.
                              16189                 :                :                      */
  860 tgl@sss.pgh.pa.us       16190   [ +  +  +  + ]:          16769 :                     if (dopt->binary_upgrade || !OidIsValid(tbinfo->reloftype))
                              16191                 :                :                     {
 4039 andrew@dunslane.net     16192                 :          16753 :                         appendPQExpBuffer(q, " %s",
 2741 tgl@sss.pgh.pa.us       16193                 :          16753 :                                           tbinfo->atttypnames[j]);
                              16194                 :                :                     }
                              16195                 :                : 
 1770 alvherre@alvh.no-ip.    16196         [ +  + ]:          16769 :                     if (print_default)
                              16197                 :                :                     {
 1842 peter@eisentraut.org    16198         [ +  + ]:            640 :                         if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED)
                              16199                 :            274 :                             appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED",
                              16200                 :            274 :                                               tbinfo->attrdefs[j]->adef_expr);
                              16201                 :                :                         else
                              16202                 :            366 :                             appendPQExpBuffer(q, " DEFAULT %s",
                              16203                 :            366 :                                               tbinfo->attrdefs[j]->adef_expr);
                              16204                 :                :                     }
                              16205                 :                : 
                              16206                 :                : 
 1770 alvherre@alvh.no-ip.    16207         [ +  + ]:          16769 :                     if (print_notnull)
                              16208                 :                :                     {
  233 alvherre@alvh.no-ip.    16209         [ +  + ]:GNC        1821 :                         if (tbinfo->notnull_constrs[j][0] == '\0')
                              16210                 :            605 :                             appendPQExpBufferStr(q, " NOT NULL");
                              16211                 :                :                         else
                              16212                 :           1216 :                             appendPQExpBuffer(q, " CONSTRAINT %s NOT NULL",
                              16213                 :           1216 :                                               fmtId(tbinfo->notnull_constrs[j]));
                              16214                 :                : 
                              16215         [ +  + ]:           1821 :                         if (tbinfo->notnull_noinh[j])
                              16216                 :            804 :                             appendPQExpBufferStr(q, " NO INHERIT");
                              16217                 :                :                     }
                              16218                 :                : 
                              16219                 :                :                     /* Add collation if not default for the type */
 4039 andrew@dunslane.net     16220         [ +  + ]:CBC       16769 :                     if (OidIsValid(tbinfo->attcollation[j]))
                              16221                 :                :                     {
                              16222                 :                :                         CollInfo   *coll;
                              16223                 :                : 
                              16224                 :             69 :                         coll = findCollationByOid(tbinfo->attcollation[j]);
                              16225         [ +  - ]:             69 :                         if (coll)
 2239 tgl@sss.pgh.pa.us       16226                 :             69 :                             appendPQExpBuffer(q, " COLLATE %s",
                              16227                 :             69 :                                               fmtQualifiedDumpable(coll));
                              16228                 :                :                     }
                              16229                 :                :                 }
                              16230                 :                :             }
                              16231                 :                : 
                              16232                 :                :             /*
                              16233                 :                :              * Add non-inherited CHECK constraints, if any.
                              16234                 :                :              *
                              16235                 :                :              * For partitions, we need to include check constraints even if
                              16236                 :                :              * they're not defined locally, because the ALTER TABLE ATTACH
                              16237                 :                :              * PARTITION that we'll emit later expects the constraint to be
                              16238                 :                :              * there.  (No need to fix conislocal: ATTACH PARTITION does that)
                              16239                 :                :              */
 4039 andrew@dunslane.net     16240         [ +  + ]:           5267 :             for (j = 0; j < tbinfo->ncheck; j++)
                              16241                 :                :             {
                              16242                 :            558 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              16243                 :                : 
 1770 alvherre@alvh.no-ip.    16244         [ +  + ]:            558 :                 if (constr->separate ||
                              16245   [ +  +  +  + ]:            518 :                     (!constr->conislocal && !tbinfo->ispartition))
 4039 andrew@dunslane.net     16246                 :             81 :                     continue;
                              16247                 :                : 
                              16248         [ +  + ]:            477 :                 if (actual_atts == 0)
 3800 heikki.linnakangas@i    16249                 :             16 :                     appendPQExpBufferStr(q, " (\n    ");
                              16250                 :                :                 else
                              16251                 :            461 :                     appendPQExpBufferStr(q, ",\n    ");
                              16252                 :                : 
 4039 andrew@dunslane.net     16253                 :            477 :                 appendPQExpBuffer(q, "CONSTRAINT %s ",
                              16254                 :            477 :                                   fmtId(constr->dobj.name));
 3800 heikki.linnakangas@i    16255                 :            477 :                 appendPQExpBufferStr(q, constr->condef);
                              16256                 :                : 
 4039 andrew@dunslane.net     16257                 :            477 :                 actual_atts++;
                              16258                 :                :             }
                              16259                 :                : 
                              16260         [ +  + ]:           4709 :             if (actual_atts)
 3800 heikki.linnakangas@i    16261                 :           4470 :                 appendPQExpBufferStr(q, "\n)");
  860 tgl@sss.pgh.pa.us       16262   [ +  +  -  + ]:            239 :             else if (!(OidIsValid(tbinfo->reloftype) && !dopt->binary_upgrade))
                              16263                 :                :             {
                              16264                 :                :                 /*
                              16265                 :                :                  * No attributes? we must have a parenthesized attribute list,
                              16266                 :                :                  * even though empty, when not using the OF TYPE syntax.
                              16267                 :                :                  */
 3800 heikki.linnakangas@i    16268                 :            227 :                 appendPQExpBufferStr(q, " (\n)");
                              16269                 :                :             }
                              16270                 :                : 
                              16271                 :                :             /*
                              16272                 :                :              * Emit the INHERITS clause (not for partitions), except in
                              16273                 :                :              * binary-upgrade mode.
                              16274                 :                :              */
 1770 alvherre@alvh.no-ip.    16275   [ +  +  +  + ]:           4709 :             if (numParents > 0 && !tbinfo->ispartition &&
 2537 sfrost@snowman.net      16276         [ +  + ]:            355 :                 !dopt->binary_upgrade)
                              16277                 :                :             {
 3800 heikki.linnakangas@i    16278                 :            304 :                 appendPQExpBufferStr(q, "\nINHERITS (");
 4039 andrew@dunslane.net     16279         [ +  + ]:            636 :                 for (k = 0; k < numParents; k++)
                              16280                 :                :                 {
                              16281                 :            332 :                     TableInfo  *parentRel = parents[k];
                              16282                 :                : 
                              16283         [ +  + ]:            332 :                     if (k > 0)
 3800 heikki.linnakangas@i    16284                 :             28 :                         appendPQExpBufferStr(q, ", ");
 2239 tgl@sss.pgh.pa.us       16285                 :            332 :                     appendPQExpBufferStr(q, fmtQualifiedDumpable(parentRel));
                              16286                 :                :                 }
 3800 heikki.linnakangas@i    16287                 :            304 :                 appendPQExpBufferChar(q, ')');
                              16288                 :                :             }
                              16289                 :                : 
 2685 rhaas@postgresql.org    16290         [ +  + ]:           4709 :             if (tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
  860 tgl@sss.pgh.pa.us       16291                 :            512 :                 appendPQExpBuffer(q, "\nPARTITION BY %s", partkeydef);
                              16292                 :                : 
 4039 andrew@dunslane.net     16293         [ +  + ]:           4709 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
                              16294                 :             38 :                 appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
                              16295                 :                :         }
                              16296                 :                : 
 3025 tgl@sss.pgh.pa.us       16297   [ +  +  -  + ]:          10000 :         if (nonemptyReloptions(tbinfo->reloptions) ||
                              16298                 :           4927 :             nonemptyReloptions(tbinfo->toast_reloptions))
                              16299                 :                :         {
 5421 bruce@momjian.us        16300                 :            146 :             bool        addcomma = false;
                              16301                 :                : 
 3800 heikki.linnakangas@i    16302                 :            146 :             appendPQExpBufferStr(q, "\nWITH (");
 3025 tgl@sss.pgh.pa.us       16303         [ +  - ]:            146 :             if (nonemptyReloptions(tbinfo->reloptions))
                              16304                 :                :             {
 5550 alvherre@alvh.no-ip.    16305                 :            146 :                 addcomma = true;
 2900 dean.a.rasheed@gmail    16306                 :            146 :                 appendReloptionsArrayAH(q, tbinfo->reloptions, "", fout);
                              16307                 :                :             }
 3025 tgl@sss.pgh.pa.us       16308         [ +  + ]:            146 :             if (nonemptyReloptions(tbinfo->toast_reloptions))
                              16309                 :                :             {
                              16310         [ +  - ]:              5 :                 if (addcomma)
                              16311                 :              5 :                     appendPQExpBufferStr(q, ", ");
 2900 dean.a.rasheed@gmail    16312                 :              5 :                 appendReloptionsArrayAH(q, tbinfo->toast_reloptions, "toast.",
                              16313                 :                :                                         fout);
                              16314                 :                :             }
 3800 heikki.linnakangas@i    16315                 :            146 :             appendPQExpBufferChar(q, ')');
                              16316                 :                :         }
                              16317                 :                : 
                              16318                 :                :         /* Dump generic options if any */
 4852 rhaas@postgresql.org    16319   [ +  +  +  + ]:           5073 :         if (ftoptions && ftoptions[0])
 4483 peter_e@gmx.net         16320                 :             36 :             appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);
                              16321                 :                : 
                              16322                 :                :         /*
                              16323                 :                :          * For materialized views, create the AS clause just like a view. At
                              16324                 :                :          * this point, we always mark the view as not populated.
                              16325                 :                :          */
 4060 kgrittn@postgresql.o    16326         [ +  + ]:           5073 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              16327                 :                :         {
                              16328                 :                :             PQExpBuffer result;
                              16329                 :                : 
                              16330                 :            364 :             result = createViewAsClause(fout, tbinfo);
                              16331                 :            364 :             appendPQExpBuffer(q, " AS\n%s\n  WITH NO DATA;\n",
                              16332                 :                :                               result->data);
                              16333                 :            364 :             destroyPQExpBuffer(result);
                              16334                 :                :         }
                              16335                 :                :         else
 3800 heikki.linnakangas@i    16336                 :           4709 :             appendPQExpBufferStr(q, ";\n");
                              16337                 :                : 
                              16338                 :                :         /* Materialized views can depend on extensions */
 1495 alvherre@alvh.no-ip.    16339         [ +  + ]:           5073 :         if (tbinfo->relkind == RELKIND_MATVIEW)
                              16340                 :            364 :             append_depends_on_extension(fout, q, &tbinfo->dobj,
                              16341                 :                :                                         "pg_catalog.pg_class",
                              16342                 :                :                                         "MATERIALIZED VIEW",
                              16343                 :                :                                         qualrelname);
                              16344                 :                : 
                              16345                 :                :         /*
                              16346                 :                :          * in binary upgrade mode, update the catalog with any missing values
                              16347                 :                :          * that might be present.
                              16348                 :                :          */
 2123 andrew@dunslane.net     16349         [ +  + ]:           5073 :         if (dopt->binary_upgrade)
                              16350                 :                :         {
                              16351         [ +  + ]:           3659 :             for (j = 0; j < tbinfo->numatts; j++)
                              16352                 :                :             {
                              16353         [ +  + ]:           2947 :                 if (tbinfo->attmissingval[j][0] != '\0')
                              16354                 :                :                 {
                              16355                 :              2 :                     appendPQExpBufferStr(q, "\n-- set missing value.\n");
                              16356                 :              2 :                     appendPQExpBufferStr(q,
                              16357                 :                :                                          "SELECT pg_catalog.binary_upgrade_set_missing_value(");
                              16358                 :              2 :                     appendStringLiteralAH(q, qualrelname, fout);
                              16359                 :              2 :                     appendPQExpBufferStr(q, "::pg_catalog.regclass,");
                              16360                 :              2 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
  586 drowley@postgresql.o    16361                 :              2 :                     appendPQExpBufferChar(q, ',');
 2123 andrew@dunslane.net     16362                 :              2 :                     appendStringLiteralAH(q, tbinfo->attmissingval[j], fout);
                              16363                 :              2 :                     appendPQExpBufferStr(q, ");\n\n");
                              16364                 :                :                 }
                              16365                 :                :             }
                              16366                 :                :         }
                              16367                 :                : 
                              16368                 :                :         /*
                              16369                 :                :          * To create binary-compatible heap files, we have to ensure the same
                              16370                 :                :          * physical column order, including dropped columns, as in the
                              16371                 :                :          * original.  Therefore, we create dropped columns above and drop them
                              16372                 :                :          * here, also updating their attlen/attalign values so that the
                              16373                 :                :          * dropped column can be skipped properly.  (We do not bother with
                              16374                 :                :          * restoring the original attbyval setting.)  Also, inheritance
                              16375                 :                :          * relationships are set up by doing ALTER TABLE INHERIT rather than
                              16376                 :                :          * using an INHERITS clause --- the latter would possibly mess up the
                              16377                 :                :          * column order.  That also means we have to take care about setting
                              16378                 :                :          * attislocal correctly, plus fix up any inherited CHECK constraints.
                              16379                 :                :          * Analogously, we set up typed tables using ALTER TABLE / OF here.
                              16380                 :                :          *
                              16381                 :                :          * We process foreign and partitioned tables here, even though they
                              16382                 :                :          * lack heap storage, because they can participate in inheritance
                              16383                 :                :          * relationships and we want this stuff to be consistent across the
                              16384                 :                :          * inheritance tree.  We can exclude indexes, toast tables, sequences
                              16385                 :                :          * and matviews, even though they have storage, because we don't
                              16386                 :                :          * support altering or dropping columns in them, nor can they be part
                              16387                 :                :          * of inheritance trees.
                              16388                 :                :          */
 3311 tgl@sss.pgh.pa.us       16389         [ +  + ]:           5073 :         if (dopt->binary_upgrade &&
                              16390         [ +  + ]:            712 :             (tbinfo->relkind == RELKIND_RELATION ||
 2685 rhaas@postgresql.org    16391         [ +  + ]:            101 :              tbinfo->relkind == RELKIND_FOREIGN_TABLE ||
                              16392         [ +  + ]:            100 :              tbinfo->relkind == RELKIND_PARTITIONED_TABLE))
                              16393                 :                :         {
 5535 bruce@momjian.us        16394         [ +  + ]:           3622 :             for (j = 0; j < tbinfo->numatts; j++)
                              16395                 :                :             {
                              16396         [ +  + ]:           2927 :                 if (tbinfo->attisdropped[j])
                              16397                 :                :                 {
 3800 heikki.linnakangas@i    16398                 :             79 :                     appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped column.\n");
 5400 tgl@sss.pgh.pa.us       16399                 :             79 :                     appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
                              16400                 :                :                                       "SET attlen = %d, "
                              16401                 :                :                                       "attalign = '%c', attbyval = false\n"
                              16402                 :                :                                       "WHERE attname = ",
                              16403                 :             79 :                                       tbinfo->attlen[j],
                              16404                 :             79 :                                       tbinfo->attalign[j]);
                              16405                 :             79 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 3800 heikki.linnakangas@i    16406                 :             79 :                     appendPQExpBufferStr(q, "\n  AND attrelid = ");
 2239 tgl@sss.pgh.pa.us       16407                 :             79 :                     appendStringLiteralAH(q, qualrelname, fout);
 3800 heikki.linnakangas@i    16408                 :             79 :                     appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              16409                 :                : 
 2685 rhaas@postgresql.org    16410         [ +  + ]:             79 :                     if (tbinfo->relkind == RELKIND_RELATION ||
                              16411         [ +  - ]:             16 :                         tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 3946 andrew@dunslane.net     16412                 :             79 :                         appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                              16413                 :                :                                           qualrelname);
                              16414                 :                :                     else
 3311 tgl@sss.pgh.pa.us       16415                 :UBC           0 :                         appendPQExpBuffer(q, "ALTER FOREIGN TABLE ONLY %s ",
                              16416                 :                :                                           qualrelname);
 5535 bruce@momjian.us        16417                 :CBC          79 :                     appendPQExpBuffer(q, "DROP COLUMN %s;\n",
                              16418                 :             79 :                                       fmtId(tbinfo->attnames[j]));
                              16419                 :                :                 }
 5400 tgl@sss.pgh.pa.us       16420         [ +  + ]:           2848 :                 else if (!tbinfo->attislocal[j])
                              16421                 :                :                 {
 3800 heikki.linnakangas@i    16422                 :            561 :                     appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited column.\n");
                              16423                 :            561 :                     appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
                              16424                 :                :                                          "SET attislocal = false\n"
                              16425                 :                :                                          "WHERE attname = ");
 5400 tgl@sss.pgh.pa.us       16426                 :            561 :                     appendStringLiteralAH(q, tbinfo->attnames[j], fout);
 3800 heikki.linnakangas@i    16427                 :            561 :                     appendPQExpBufferStr(q, "\n  AND attrelid = ");
 2239 tgl@sss.pgh.pa.us       16428                 :            561 :                     appendStringLiteralAH(q, qualrelname, fout);
 3800 heikki.linnakangas@i    16429                 :            561 :                     appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              16430                 :                : 
                              16431                 :                :                     /*
                              16432                 :                :                      * If a not-null constraint comes from inheritance, reset
                              16433                 :                :                      * conislocal.  The inhcount is fixed later.
                              16434                 :                :                      */
  233 alvherre@alvh.no-ip.    16435         [ +  + ]:GNC         561 :                     if (tbinfo->notnull_constrs[j] != NULL &&
                              16436         [ +  + ]:             83 :                         !tbinfo->notnull_throwaway[j] &&
                              16437         [ +  + ]:             63 :                         tbinfo->notnull_inh[j] &&
                              16438         [ +  + ]:             48 :                         !tbinfo->ispartition)
                              16439                 :                :                     {
                              16440                 :             15 :                         appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
                              16441                 :                :                                              "SET conislocal = false\n"
                              16442                 :                :                                              "WHERE contype = 'n' AND conrelid = ");
                              16443                 :             15 :                         appendStringLiteralAH(q, qualrelname, fout);
                              16444                 :             15 :                         appendPQExpBufferStr(q, "::pg_catalog.regclass AND\n"
                              16445                 :                :                                              "conname = ");
                              16446                 :             15 :                         appendStringLiteralAH(q, tbinfo->notnull_constrs[j], fout);
                              16447                 :             15 :                         appendPQExpBufferStr(q, ";\n");
                              16448                 :                :                     }
                              16449                 :                :                 }
                              16450                 :                :             }
                              16451                 :                : 
                              16452                 :                :             /*
                              16453                 :                :              * Add inherited CHECK constraints, if any.
                              16454                 :                :              *
                              16455                 :                :              * For partitions, they were already dumped, and conislocal
                              16456                 :                :              * doesn't need fixing.
                              16457                 :                :              */
 5400 tgl@sss.pgh.pa.us       16458         [ +  + ]:CBC         746 :             for (k = 0; k < tbinfo->ncheck; k++)
                              16459                 :                :             {
                              16460                 :             51 :                 ConstraintInfo *constr = &(tbinfo->checkexprs[k]);
                              16461                 :                : 
 1770 alvherre@alvh.no-ip.    16462   [ +  +  +  +  :             51 :                 if (constr->separate || constr->conislocal || tbinfo->ispartition)
                                              +  + ]
 5400 tgl@sss.pgh.pa.us       16463                 :             49 :                     continue;
                              16464                 :                : 
 3800 heikki.linnakangas@i    16465                 :              2 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
 1486 alvherre@alvh.no-ip.    16466                 :              2 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s %s;\n",
                              16467                 :                :                                   foreign, qualrelname,
                              16468                 :              2 :                                   fmtId(constr->dobj.name),
                              16469                 :                :                                   constr->condef);
 3800 heikki.linnakangas@i    16470                 :              2 :                 appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
                              16471                 :                :                                      "SET conislocal = false\n"
                              16472                 :                :                                      "WHERE contype = 'c' AND conname = ");
 5400 tgl@sss.pgh.pa.us       16473                 :              2 :                 appendStringLiteralAH(q, constr->dobj.name, fout);
 3800 heikki.linnakangas@i    16474                 :              2 :                 appendPQExpBufferStr(q, "\n  AND conrelid = ");
 2239 tgl@sss.pgh.pa.us       16475                 :              2 :                 appendStringLiteralAH(q, qualrelname, fout);
 3800 heikki.linnakangas@i    16476                 :              2 :                 appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              16477                 :                :             }
                              16478                 :                : 
 1770 alvherre@alvh.no-ip.    16479   [ +  +  +  + ]:            695 :             if (numParents > 0 && !tbinfo->ispartition)
                              16480                 :                :             {
                              16481                 :             51 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
 5400 tgl@sss.pgh.pa.us       16482         [ +  + ]:            109 :                 for (k = 0; k < numParents; k++)
                              16483                 :                :                 {
                              16484                 :             58 :                     TableInfo  *parentRel = parents[k];
                              16485                 :                : 
 1486 alvherre@alvh.no-ip.    16486                 :             58 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s INHERIT %s;\n", foreign,
                              16487                 :                :                                       qualrelname,
 1770                         16488                 :             58 :                                       fmtQualifiedDumpable(parentRel));
                              16489                 :                :                 }
                              16490                 :                :             }
                              16491                 :                : 
  860 tgl@sss.pgh.pa.us       16492         [ +  + ]:            695 :             if (OidIsValid(tbinfo->reloftype))
                              16493                 :                :             {
 3800 heikki.linnakangas@i    16494                 :              6 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
 4736 peter_e@gmx.net         16495                 :              6 :                 appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
                              16496                 :                :                                   qualrelname,
  860 tgl@sss.pgh.pa.us       16497                 :              6 :                                   getFormattedTypeName(fout, tbinfo->reloftype,
                              16498                 :                :                                                        zeroIsError));
                              16499                 :                :             }
                              16500                 :                :         }
                              16501                 :                : 
                              16502                 :                :         /*
                              16503                 :                :          * In binary_upgrade mode, arrange to restore the old relfrozenxid and
                              16504                 :                :          * relminmxid of all vacuumable relations.  (While vacuum.c processes
                              16505                 :                :          * TOAST tables semi-independently, here we see them only as children
                              16506                 :                :          * of other relations; so this "if" lacks RELKIND_TOASTVALUE, and the
                              16507                 :                :          * child toast table is handled below.)
                              16508                 :                :          */
 2244                         16509         [ +  + ]:           5073 :         if (dopt->binary_upgrade &&
                              16510         [ +  + ]:            712 :             (tbinfo->relkind == RELKIND_RELATION ||
                              16511         [ +  + ]:            101 :              tbinfo->relkind == RELKIND_MATVIEW))
                              16512                 :                :         {
 3574 bruce@momjian.us        16513                 :            628 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid and relminmxid\n");
 5400 tgl@sss.pgh.pa.us       16514                 :            628 :             appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              16515                 :                :                               "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              16516                 :                :                               "WHERE oid = ",
 3574 bruce@momjian.us        16517                 :            628 :                               tbinfo->frozenxid, tbinfo->minmxid);
 2239 tgl@sss.pgh.pa.us       16518                 :            628 :             appendStringLiteralAH(q, qualrelname, fout);
 3800 heikki.linnakangas@i    16519                 :            628 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              16520                 :                : 
 4755 bruce@momjian.us        16521         [ +  + ]:            628 :             if (tbinfo->toast_oid)
                              16522                 :                :             {
                              16523                 :                :                 /*
                              16524                 :                :                  * The toast table will have the same OID at restore, so we
                              16525                 :                :                  * can safely target it by OID.
                              16526                 :                :                  */
 3574                         16527                 :            272 :                 appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid and relminmxid\n");
 4755                         16528                 :            272 :                 appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                              16529                 :                :                                   "SET relfrozenxid = '%u', relminmxid = '%u'\n"
                              16530                 :                :                                   "WHERE oid = '%u';\n",
 3574                         16531                 :            272 :                                   tbinfo->toast_frozenxid,
                              16532                 :            272 :                                   tbinfo->toast_minmxid, tbinfo->toast_oid);
                              16533                 :                :             }
                              16534                 :                :         }
                              16535                 :                : 
                              16536                 :                :         /*
                              16537                 :                :          * In binary_upgrade mode, restore matviews' populated status by
                              16538                 :                :          * poking pg_class directly.  This is pretty ugly, but we can't use
                              16539                 :                :          * REFRESH MATERIALIZED VIEW since it's possible that some underlying
                              16540                 :                :          * matview is not populated even though this matview is; in any case,
                              16541                 :                :          * we want to transfer the matview's heap storage, not run REFRESH.
                              16542                 :                :          */
 3470 alvherre@alvh.no-ip.    16543   [ +  +  +  + ]:           5073 :         if (dopt->binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
 3996 tgl@sss.pgh.pa.us       16544         [ +  + ]:             17 :             tbinfo->relispopulated)
                              16545                 :                :         {
 3800 heikki.linnakangas@i    16546                 :             15 :             appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
                              16547                 :             15 :             appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
                              16548                 :                :                                  "SET relispopulated = 't'\n"
                              16549                 :                :                                  "WHERE oid = ");
 2239 tgl@sss.pgh.pa.us       16550                 :             15 :             appendStringLiteralAH(q, qualrelname, fout);
 3800 heikki.linnakangas@i    16551                 :             15 :             appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                              16552                 :                :         }
                              16553                 :                : 
                              16554                 :                :         /*
                              16555                 :                :          * Dump additional per-column properties that we can't handle in the
                              16556                 :                :          * main CREATE TABLE command.
                              16557                 :                :          */
 7893 bruce@momjian.us        16558         [ +  + ]:          23174 :         for (j = 0; j < tbinfo->numatts; j++)
                              16559                 :                :         {
                              16560                 :                :             /* None of this applies to dropped columns */
 4447 tgl@sss.pgh.pa.us       16561         [ +  + ]:          18101 :             if (tbinfo->attisdropped[j])
                              16562                 :            426 :                 continue;
                              16563                 :                : 
                              16564                 :                :             /*
                              16565                 :                :              * If we didn't dump the column definition explicitly above, and
                              16566                 :                :              * it is not-null and did not inherit that property from a parent,
                              16567                 :                :              * we have to mark it separately.
                              16568                 :                :              */
 3470 alvherre@alvh.no-ip.    16569         [ +  + ]:          17675 :             if (!shouldPrintColumn(dopt, tbinfo, j) &&
  233 alvherre@alvh.no-ip.    16570         [ +  + ]:GNC         472 :                 tbinfo->notnull_constrs[j] != NULL &&
                              16571   [ +  +  +  -  :            103 :                 (!tbinfo->notnull_inh[j] && !tbinfo->ispartition && !dopt->binary_upgrade))
                                              +  - ]
                              16572                 :                :             {
                              16573                 :                :                 /* No constraint name desired? */
                              16574         [ +  + ]:             12 :                 if (tbinfo->notnull_constrs[j][0] == '\0')
                              16575                 :              8 :                     appendPQExpBuffer(q,
                              16576                 :                :                                       "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET NOT NULL;\n",
                              16577                 :                :                                       foreign, qualrelname,
                              16578                 :              8 :                                       fmtId(tbinfo->attnames[j]));
                              16579                 :                :                 else
                              16580                 :              8 :                     appendPQExpBuffer(q,
                              16581                 :                :                                       "ALTER %sTABLE ONLY %s ADD CONSTRAINT %s NOT NULL %s;\n",
                              16582                 :                :                                       foreign, qualrelname,
                              16583                 :              4 :                                       tbinfo->notnull_constrs[j],
                              16584                 :              4 :                                       fmtId(tbinfo->attnames[j]));
                              16585                 :                :             }
                              16586                 :                : 
                              16587                 :                :             /*
                              16588                 :                :              * Dump per-column statistics information. We only issue an ALTER
                              16589                 :                :              * TABLE statement if the attstattarget entry for this column is
                              16590                 :                :              * not the default value.
                              16591                 :                :              */
 4447 tgl@sss.pgh.pa.us       16592         [ +  + ]:CBC       17675 :             if (tbinfo->attstattarget[j] >= 0)
 1486 alvherre@alvh.no-ip.    16593                 :             36 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STATISTICS %d;\n",
                              16594                 :                :                                   foreign, qualrelname,
                              16595                 :             36 :                                   fmtId(tbinfo->attnames[j]),
 7928 tgl@sss.pgh.pa.us       16596                 :             36 :                                   tbinfo->attstattarget[j]);
                              16597                 :                : 
                              16598                 :                :             /*
                              16599                 :                :              * Dump per-column storage information.  The statement is only
                              16600                 :                :              * dumped if the storage has been changed from the type's default.
                              16601                 :                :              */
 4447                         16602         [ +  + ]:          17675 :             if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
                              16603                 :                :             {
 7559 bruce@momjian.us        16604   [ +  +  -  +  :             87 :                 switch (tbinfo->attstorage[j])
                                                 - ]
                              16605                 :                :                 {
 1502 tgl@sss.pgh.pa.us       16606                 :             10 :                     case TYPSTORAGE_PLAIN:
 7696 bruce@momjian.us        16607                 :             10 :                         storage = "PLAIN";
                              16608                 :             10 :                         break;
 1502 tgl@sss.pgh.pa.us       16609                 :             41 :                     case TYPSTORAGE_EXTERNAL:
 7696 bruce@momjian.us        16610                 :             41 :                         storage = "EXTERNAL";
                              16611                 :             41 :                         break;
 1502 tgl@sss.pgh.pa.us       16612                 :UBC           0 :                     case TYPSTORAGE_EXTENDED:
 7696 bruce@momjian.us        16613                 :              0 :                         storage = "EXTENDED";
                              16614                 :              0 :                         break;
 1502 tgl@sss.pgh.pa.us       16615                 :CBC          36 :                     case TYPSTORAGE_MAIN:
                              16616                 :             36 :                         storage = "MAIN";
                              16617                 :             36 :                         break;
 7696 bruce@momjian.us        16618                 :UBC           0 :                     default:
                              16619                 :              0 :                         storage = NULL;
                              16620                 :                :                 }
                              16621                 :                : 
                              16622                 :                :                 /*
                              16623                 :                :                  * Only dump the statement if it's a storage type we recognize
                              16624                 :                :                  */
 7559 bruce@momjian.us        16625         [ +  - ]:CBC          87 :                 if (storage != NULL)
 1486 alvherre@alvh.no-ip.    16626                 :             87 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET STORAGE %s;\n",
                              16627                 :                :                                       foreign, qualrelname,
                              16628                 :             87 :                                       fmtId(tbinfo->attnames[j]),
                              16629                 :                :                                       storage);
                              16630                 :                :             }
                              16631                 :                : 
                              16632                 :                :             /*
                              16633                 :                :              * Dump per-column compression, if it's been set.
                              16634                 :                :              */
 1121 tgl@sss.pgh.pa.us       16635         [ +  + ]:          17675 :             if (!dopt->no_toast_compression)
                              16636                 :                :             {
                              16637                 :                :                 const char *cmname;
                              16638                 :                : 
                              16639      [ +  +  + ]:          17592 :                 switch (tbinfo->attcompression[j])
                              16640                 :                :                 {
                              16641                 :             55 :                     case 'p':
                              16642                 :             55 :                         cmname = "pglz";
                              16643                 :             55 :                         break;
                              16644                 :            100 :                     case 'l':
                              16645                 :            100 :                         cmname = "lz4";
                              16646                 :            100 :                         break;
                              16647                 :          17437 :                     default:
                              16648                 :          17437 :                         cmname = NULL;
                              16649                 :          17437 :                         break;
                              16650                 :                :                 }
                              16651                 :                : 
 1053                         16652         [ +  + ]:          17592 :                 if (cmname != NULL)
 1121                         16653                 :            155 :                     appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n",
                              16654                 :                :                                       foreign, qualrelname,
                              16655                 :            155 :                                       fmtId(tbinfo->attnames[j]),
                              16656                 :                :                                       cmname);
                              16657                 :                :             }
                              16658                 :                : 
                              16659                 :                :             /*
                              16660                 :                :              * Dump per-column attributes.
                              16661                 :                :              */
 1053                         16662         [ +  + ]:          17675 :             if (tbinfo->attoptions[j][0] != '\0')
                              16663                 :             36 :                 appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET (%s);\n",
                              16664                 :                :                                   foreign, qualrelname,
                              16665                 :             36 :                                   fmtId(tbinfo->attnames[j]),
                              16666                 :             36 :                                   tbinfo->attoptions[j]);
                              16667                 :                : 
                              16668                 :                :             /*
                              16669                 :                :              * Dump per-column fdw options.
                              16670                 :                :              */
                              16671         [ +  + ]:          17675 :             if (tbinfo->relkind == RELKIND_FOREIGN_TABLE &&
                              16672         [ +  + ]:             38 :                 tbinfo->attfdwoptions[j][0] != '\0')
                              16673                 :             36 :                 appendPQExpBuffer(q,
                              16674                 :                :                                   "ALTER FOREIGN TABLE %s ALTER COLUMN %s OPTIONS (\n"
                              16675                 :                :                                   "    %s\n"
                              16676                 :                :                                   ");\n",
                              16677                 :                :                                   qualrelname,
                              16678                 :             36 :                                   fmtId(tbinfo->attnames[j]),
                              16679                 :             36 :                                   tbinfo->attfdwoptions[j]);
                              16680                 :                :         }                       /* end loop over columns */
                              16681                 :                : 
  668 peter@eisentraut.org    16682                 :           5073 :         free(partkeydef);
                              16683                 :           5073 :         free(ftoptions);
                              16684                 :           5073 :         free(srvname);
                              16685                 :                :     }
                              16686                 :                : 
                              16687                 :                :     /*
                              16688                 :                :      * dump properties we only have ALTER TABLE syntax for
                              16689                 :                :      */
 3311 tgl@sss.pgh.pa.us       16690         [ +  + ]:           5422 :     if ((tbinfo->relkind == RELKIND_RELATION ||
 2685 rhaas@postgresql.org    16691         [ +  + ]:           1263 :          tbinfo->relkind == RELKIND_PARTITIONED_TABLE ||
 3311 tgl@sss.pgh.pa.us       16692         [ +  + ]:            751 :          tbinfo->relkind == RELKIND_MATVIEW) &&
 3808 peter_e@gmx.net         16693         [ +  + ]:           5035 :         tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
                              16694                 :                :     {
 3810 rhaas@postgresql.org    16695         [ +  - ]:             64 :         if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
                              16696                 :                :         {
                              16697                 :                :             /* nothing to do, will be set when the index is dumped */
                              16698                 :                :         }
                              16699         [ +  - ]:             64 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
                              16700                 :                :         {
                              16701                 :             64 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
                              16702                 :                :                               qualrelname);
                              16703                 :                :         }
 3810 rhaas@postgresql.org    16704         [ #  # ]:UBC           0 :         else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
                              16705                 :                :         {
                              16706                 :              0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
                              16707                 :                :                               qualrelname);
                              16708                 :                :         }
                              16709                 :                :     }
                              16710                 :                : 
 3115 sfrost@snowman.net      16711         [ +  + ]:CBC        5422 :     if (tbinfo->forcerowsec)
                              16712                 :              5 :         appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
                              16713                 :                :                           qualrelname);
                              16714                 :                : 
 3470 alvherre@alvh.no-ip.    16715         [ +  + ]:           5422 :     if (dopt->binary_upgrade)
 2239 tgl@sss.pgh.pa.us       16716                 :            760 :         binary_upgrade_extension_member(q, &tbinfo->dobj,
                              16717                 :                :                                         reltypename, qrelname,
                              16718                 :            760 :                                         tbinfo->dobj.namespace->dobj.name);
                              16719                 :                : 
 2930 sfrost@snowman.net      16720         [ +  - ]:           5422 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16721                 :                :     {
  863 peter@eisentraut.org    16722                 :           5422 :         char       *tablespace = NULL;
 1789 tgl@sss.pgh.pa.us       16723                 :           5422 :         char       *tableam = NULL;
                              16724                 :                : 
                              16725                 :                :         /*
                              16726                 :                :          * _selectTablespace() relies on tablespace-enabled objects in the
                              16727                 :                :          * default tablespace to have a tablespace of "" (empty string) versus
                              16728                 :                :          * non-tablespace-enabled objects to have a tablespace of NULL.
                              16729                 :                :          * getTables() sets tbinfo->reltablespace to "" for the default
                              16730                 :                :          * tablespace (not NULL).
                              16731                 :                :          */
  863 peter@eisentraut.org    16732   [ +  +  +  -  :           5422 :         if (RELKIND_HAS_TABLESPACE(tbinfo->relkind))
                                     +  -  +  -  +  
                                     +  +  +  -  +  
                                              +  - ]
                              16733                 :           5035 :             tablespace = tbinfo->reltablespace;
                              16734                 :                : 
   20 alvherre@alvh.no-ip.    16735   [ +  +  +  -  :GNC        5422 :         if (RELKIND_HAS_TABLE_AM(tbinfo->relkind) ||
                                              +  + ]
                              16736         [ +  + ]:            899 :             tbinfo->relkind == RELKIND_PARTITIONED_TABLE)
 1866 andres@anarazel.de      16737                 :CBC        5035 :             tableam = tbinfo->amname;
                              16738                 :                : 
 2930 sfrost@snowman.net      16739                 :           5422 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    16740         [ +  + ]:           5422 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              16741                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              16742                 :                :                                   .tablespace = tablespace,
                              16743                 :                :                                   .tableam = tableam,
                              16744                 :                :                                   .owner = tbinfo->rolname,
                              16745                 :                :                                   .description = reltypename,
                              16746                 :                :                                   .section = tbinfo->postponed_def ?
                              16747                 :                :                                   SECTION_POST_DATA : SECTION_PRE_DATA,
                              16748                 :                :                                   .createStmt = q->data,
                              16749                 :                :                                   .dropStmt = delq->data));
                              16750                 :                :     }
                              16751                 :                : 
                              16752                 :                :     /* Dump Table Comments */
 2930 sfrost@snowman.net      16753         [ +  + ]:           5422 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
                              16754                 :             82 :         dumpTableComment(fout, tbinfo, reltypename);
                              16755                 :                : 
                              16756                 :                :     /* Dump Table Security Labels */
                              16757         [ -  + ]:           5422 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2930 sfrost@snowman.net      16758                 :UBC           0 :         dumpTableSecLabel(fout, tbinfo, reltypename);
                              16759                 :                : 
                              16760                 :                :     /* Dump comments on inlined table constraints */
 7061 tgl@sss.pgh.pa.us       16761         [ +  + ]:CBC        5980 :     for (j = 0; j < tbinfo->ncheck; j++)
                              16762                 :                :     {
                              16763                 :            558 :         ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
                              16764                 :                : 
 5819                         16765   [ +  +  +  + ]:            558 :         if (constr->separate || !constr->conislocal)
 7061                         16766                 :            229 :             continue;
                              16767                 :                : 
  529                         16768         [ +  + ]:            329 :         if (constr->dobj.dump & DUMP_COMPONENT_COMMENT)
 2930 sfrost@snowman.net      16769                 :             41 :             dumpTableConstraintComment(fout, constr);
                              16770                 :                :     }
                              16771                 :                : 
 8010 tgl@sss.pgh.pa.us       16772                 :           5422 :     destroyPQExpBuffer(q);
                              16773                 :           5422 :     destroyPQExpBuffer(delq);
 2239                         16774                 :           5422 :     free(qrelname);
                              16775                 :           5422 :     free(qualrelname);
 8493 pjw@rhyme.com.au        16776                 :           5422 : }
                              16777                 :                : 
                              16778                 :                : /*
                              16779                 :                :  * dumpTableAttach
                              16780                 :                :  *    write to fout the commands to attach a child partition
                              16781                 :                :  *
                              16782                 :                :  * Child partitions are always made by creating them separately
                              16783                 :                :  * and then using ATTACH PARTITION, rather than using
                              16784                 :                :  * CREATE TABLE ... PARTITION OF.  This is important for preserving
                              16785                 :                :  * any possible discrepancy in column layout, to allow assigning the
                              16786                 :                :  * correct tablespace if different, and so that it's possible to restore
                              16787                 :                :  * a partition without restoring its parent.  (You'll get an error from
                              16788                 :                :  * the ATTACH PARTITION command, but that can be ignored, or skipped
                              16789                 :                :  * using "pg_restore -L" if you prefer.)  The last point motivates
                              16790                 :                :  * treating ATTACH PARTITION as a completely separate ArchiveEntry
                              16791                 :                :  * rather than emitting it within the child partition's ArchiveEntry.
                              16792                 :                :  */
                              16793                 :                : static void
 1159 peter@eisentraut.org    16794                 :           1259 : dumpTableAttach(Archive *fout, const TableAttachInfo *attachinfo)
                              16795                 :                : {
 1189 tgl@sss.pgh.pa.us       16796                 :           1259 :     DumpOptions *dopt = fout->dopt;
                              16797                 :                :     PQExpBuffer q;
                              16798                 :                :     PGresult   *res;
                              16799                 :                :     char       *partbound;
                              16800                 :                : 
                              16801                 :                :     /* Do nothing in data-only dump */
                              16802         [ +  + ]:           1259 :     if (dopt->dataOnly)
                              16803                 :             21 :         return;
                              16804                 :                : 
                              16805                 :           1238 :     q = createPQExpBuffer();
                              16806                 :                : 
  860                         16807         [ +  + ]:           1238 :     if (!fout->is_prepared[PREPQUERY_DUMPTABLEATTACH])
                              16808                 :                :     {
                              16809                 :                :         /* Set up query for partbound details */
                              16810                 :             47 :         appendPQExpBufferStr(q,
                              16811                 :                :                              "PREPARE dumpTableAttach(pg_catalog.oid) AS\n");
                              16812                 :                : 
                              16813                 :             47 :         appendPQExpBufferStr(q,
                              16814                 :                :                              "SELECT pg_get_expr(c.relpartbound, c.oid) "
                              16815                 :                :                              "FROM pg_class c "
                              16816                 :                :                              "WHERE c.oid = $1");
                              16817                 :                : 
                              16818                 :             47 :         ExecuteSqlStatement(fout, q->data);
                              16819                 :                : 
                              16820                 :             47 :         fout->is_prepared[PREPQUERY_DUMPTABLEATTACH] = true;
                              16821                 :                :     }
                              16822                 :                : 
                              16823                 :           1238 :     printfPQExpBuffer(q,
                              16824                 :                :                       "EXECUTE dumpTableAttach('%u')",
                              16825                 :           1238 :                       attachinfo->partitionTbl->dobj.catId.oid);
                              16826                 :                : 
                              16827                 :           1238 :     res = ExecuteSqlQueryForSingleRow(fout, q->data);
                              16828                 :           1238 :     partbound = PQgetvalue(res, 0, 0);
                              16829                 :                : 
                              16830                 :                :     /* Perform ALTER TABLE on the parent */
                              16831                 :           1238 :     printfPQExpBuffer(q,
                              16832                 :                :                       "ALTER TABLE ONLY %s ",
 1189                         16833                 :           1238 :                       fmtQualifiedDumpable(attachinfo->parentTbl));
                              16834                 :           1238 :     appendPQExpBuffer(q,
                              16835                 :                :                       "ATTACH PARTITION %s %s;\n",
                              16836                 :           1238 :                       fmtQualifiedDumpable(attachinfo->partitionTbl),
                              16837                 :                :                       partbound);
                              16838                 :                : 
                              16839                 :                :     /*
                              16840                 :                :      * There is no point in creating a drop query as the drop is done by table
                              16841                 :                :      * drop.  (If you think to change this, see also _printTocEntry().)
                              16842                 :                :      * Although this object doesn't really have ownership as such, set the
                              16843                 :                :      * owner field anyway to ensure that the command is run by the correct
                              16844                 :                :      * role at restore time.
                              16845                 :                :      */
                              16846                 :           1238 :     ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
                              16847                 :           1238 :                  ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              16848                 :                :                               .namespace = attachinfo->dobj.namespace->dobj.name,
                              16849                 :                :                               .owner = attachinfo->partitionTbl->rolname,
                              16850                 :                :                               .description = "TABLE ATTACH",
                              16851                 :                :                               .section = SECTION_PRE_DATA,
                              16852                 :                :                               .createStmt = q->data));
                              16853                 :                : 
  860                         16854                 :           1238 :     PQclear(res);
 1189                         16855                 :           1238 :     destroyPQExpBuffer(q);
                              16856                 :                : }
                              16857                 :                : 
                              16858                 :                : /*
                              16859                 :                :  * dumpAttrDef --- dump an attribute's default-value declaration
                              16860                 :                :  */
                              16861                 :                : static void
 1159 peter@eisentraut.org    16862                 :            818 : dumpAttrDef(Archive *fout, const AttrDefInfo *adinfo)
                              16863                 :                : {
 3014 tgl@sss.pgh.pa.us       16864                 :            818 :     DumpOptions *dopt = fout->dopt;
 7435                         16865                 :            818 :     TableInfo  *tbinfo = adinfo->adtable;
                              16866                 :            818 :     int         adnum = adinfo->adnum;
                              16867                 :                :     PQExpBuffer q;
                              16868                 :                :     PQExpBuffer delq;
                              16869                 :                :     char       *qualrelname;
                              16870                 :                :     char       *tag;
                              16871                 :                :     char       *foreign;
                              16872                 :                : 
                              16873                 :                :     /* Do nothing in data-only dump */
  860                         16874         [ -  + ]:            818 :     if (dopt->dataOnly)
 7435 tgl@sss.pgh.pa.us       16875                 :UBC           0 :         return;
                              16876                 :                : 
                              16877                 :                :     /* Skip if not "separate"; it was dumped in the table's definition */
 4447 tgl@sss.pgh.pa.us       16878         [ +  + ]:CBC         818 :     if (!adinfo->separate)
 7435                         16879                 :            640 :         return;
                              16880                 :                : 
                              16881                 :            178 :     q = createPQExpBuffer();
                              16882                 :            178 :     delq = createPQExpBuffer();
                              16883                 :                : 
 2239                         16884                 :            178 :     qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
                              16885                 :                : 
 1486 alvherre@alvh.no-ip.    16886         [ -  + ]:            178 :     foreign = tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              16887                 :                : 
                              16888                 :            178 :     appendPQExpBuffer(q,
                              16889                 :                :                       "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET DEFAULT %s;\n",
                              16890                 :            178 :                       foreign, qualrelname, fmtId(tbinfo->attnames[adnum - 1]),
 7435 tgl@sss.pgh.pa.us       16891                 :            178 :                       adinfo->adef_expr);
                              16892                 :                : 
 1486 alvherre@alvh.no-ip.    16893                 :            178 :     appendPQExpBuffer(delq, "ALTER %sTABLE %s ALTER COLUMN %s DROP DEFAULT;\n",
                              16894                 :                :                       foreign, qualrelname,
 7435 tgl@sss.pgh.pa.us       16895                 :            178 :                       fmtId(tbinfo->attnames[adnum - 1]));
                              16896                 :                : 
 2971 peter_e@gmx.net         16897                 :            178 :     tag = psprintf("%s %s", tbinfo->dobj.name, tbinfo->attnames[adnum - 1]);
                              16898                 :                : 
 2930 sfrost@snowman.net      16899         [ +  - ]:            178 :     if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              16900                 :            178 :         ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    16901                 :            178 :                      ARCHIVE_OPTS(.tag = tag,
                              16902                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              16903                 :                :                                   .owner = tbinfo->rolname,
                              16904                 :                :                                   .description = "DEFAULT",
                              16905                 :                :                                   .section = SECTION_PRE_DATA,
                              16906                 :                :                                   .createStmt = q->data,
                              16907                 :                :                                   .dropStmt = delq->data));
                              16908                 :                : 
 2971 peter_e@gmx.net         16909                 :            178 :     free(tag);
 7435 tgl@sss.pgh.pa.us       16910                 :            178 :     destroyPQExpBuffer(q);
                              16911                 :            178 :     destroyPQExpBuffer(delq);
 2239                         16912                 :            178 :     free(qualrelname);
                              16913                 :                : }
                              16914                 :                : 
                              16915                 :                : /*
                              16916                 :                :  * getAttrName: extract the correct name for an attribute
                              16917                 :                :  *
                              16918                 :                :  * The array tblInfo->attnames[] only provides names of user attributes;
                              16919                 :                :  * if a system attribute number is supplied, we have to fake it.
                              16920                 :                :  * We also do a little bit of bounds checking for safety's sake.
                              16921                 :                :  */
                              16922                 :                : static const char *
 1159 peter@eisentraut.org    16923                 :           1678 : getAttrName(int attrnum, const TableInfo *tblInfo)
                              16924                 :                : {
 8393 tgl@sss.pgh.pa.us       16925   [ +  -  +  - ]:           1678 :     if (attrnum > 0 && attrnum <= tblInfo->numatts)
 8207 bruce@momjian.us        16926                 :           1678 :         return tblInfo->attnames[attrnum - 1];
 8393 tgl@sss.pgh.pa.us       16927   [ #  #  #  #  :UBC           0 :     switch (attrnum)
                                           #  #  # ]
                              16928                 :                :     {
                              16929                 :              0 :         case SelfItemPointerAttributeNumber:
                              16930                 :              0 :             return "ctid";
                              16931                 :              0 :         case MinTransactionIdAttributeNumber:
                              16932                 :              0 :             return "xmin";
                              16933                 :              0 :         case MinCommandIdAttributeNumber:
                              16934                 :              0 :             return "cmin";
                              16935                 :              0 :         case MaxTransactionIdAttributeNumber:
                              16936                 :              0 :             return "xmax";
                              16937                 :              0 :         case MaxCommandIdAttributeNumber:
                              16938                 :              0 :             return "cmax";
                              16939                 :              0 :         case TableOidAttributeNumber:
                              16940                 :              0 :             return "tableoid";
                              16941                 :                :     }
  737                         16942                 :              0 :     pg_fatal("invalid column number %d for table \"%s\"",
                              16943                 :                :              attrnum, tblInfo->dobj.name);
                              16944                 :                :     return NULL;                /* keep compiler quiet */
                              16945                 :                : }
                              16946                 :                : 
                              16947                 :                : /*
                              16948                 :                :  * dumpIndex
                              16949                 :                :  *    write out to fout a user-defined index
                              16950                 :                :  */
                              16951                 :                : static void
 1159 peter@eisentraut.org    16952                 :CBC        2216 : dumpIndex(Archive *fout, const IndxInfo *indxinfo)
                              16953                 :                : {
 3014 tgl@sss.pgh.pa.us       16954                 :           2216 :     DumpOptions *dopt = fout->dopt;
 7435                         16955                 :           2216 :     TableInfo  *tbinfo = indxinfo->indextable;
 3944                         16956                 :           2216 :     bool        is_constraint = (indxinfo->indexconstraint != 0);
                              16957                 :                :     PQExpBuffer q;
                              16958                 :                :     PQExpBuffer delq;
                              16959                 :                :     char       *qindxname;
                              16960                 :                :     char       *qqindxname;
                              16961                 :                : 
                              16962                 :                :     /* Do nothing in data-only dump */
 3470 alvherre@alvh.no-ip.    16963         [ +  + ]:           2216 :     if (dopt->dataOnly)
 7435 tgl@sss.pgh.pa.us       16964                 :             57 :         return;
                              16965                 :                : 
                              16966                 :           2159 :     q = createPQExpBuffer();
                              16967                 :           2159 :     delq = createPQExpBuffer();
                              16968                 :                : 
 2239                         16969                 :           2159 :     qindxname = pg_strdup(fmtId(indxinfo->dobj.name));
 1495 alvherre@alvh.no-ip.    16970                 :           2159 :     qqindxname = pg_strdup(fmtQualifiedDumpable(indxinfo));
                              16971                 :                : 
                              16972                 :                :     /*
                              16973                 :                :      * If there's an associated constraint, don't dump the index per se, but
                              16974                 :                :      * do dump any comment for it.  (This is safe because dependency ordering
                              16975                 :                :      * will have ensured the constraint is emitted first.)  Note that the
                              16976                 :                :      * emitted comment has to be shown as depending on the constraint, not the
                              16977                 :                :      * index, in such cases.
                              16978                 :                :      */
 3944 tgl@sss.pgh.pa.us       16979         [ +  + ]:           2159 :     if (!is_constraint)
                              16980                 :                :     {
 1944 michael@paquier.xyz     16981                 :            989 :         char       *indstatcols = indxinfo->indstatcols;
                              16982                 :            989 :         char       *indstatvals = indxinfo->indstatvals;
                              16983                 :            989 :         char      **indstatcolsarray = NULL;
                              16984                 :            989 :         char      **indstatvalsarray = NULL;
 1242                         16985                 :            989 :         int         nstatcols = 0;
                              16986                 :            989 :         int         nstatvals = 0;
                              16987                 :                : 
 3470 alvherre@alvh.no-ip.    16988         [ +  + ]:            989 :         if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    16989                 :            153 :             binary_upgrade_set_pg_class_oids(fout, q,
                              16990                 :            153 :                                              indxinfo->dobj.catId.oid, true);
                              16991                 :                : 
                              16992                 :                :         /* Plain secondary index */
 7435 tgl@sss.pgh.pa.us       16993                 :            989 :         appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
                              16994                 :                : 
                              16995                 :                :         /*
                              16996                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              16997                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              16998                 :                :          * similar code in dumpConstraint!
                              16999                 :                :          */
                              17000                 :                : 
                              17001                 :                :         /* If the index is clustered, we need to record that. */
                              17002         [ -  + ]:            989 :         if (indxinfo->indisclustered)
                              17003                 :                :         {
 7435 tgl@sss.pgh.pa.us       17004                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2239                         17005                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              17006                 :                :             /* index name is not qualified in this syntax */
 7435                         17007                 :              0 :             appendPQExpBuffer(q, " ON %s;\n",
                              17008                 :                :                               qindxname);
                              17009                 :                :         }
                              17010                 :                : 
                              17011                 :                :         /*
                              17012                 :                :          * If the index has any statistics on some of its columns, generate
                              17013                 :                :          * the associated ALTER INDEX queries.
                              17014                 :                :          */
 1242 michael@paquier.xyz     17015   [ +  +  -  + ]:CBC         989 :         if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0)
                              17016                 :                :         {
                              17017                 :                :             int         j;
                              17018                 :                : 
                              17019         [ -  + ]:             36 :             if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols))
  737 tgl@sss.pgh.pa.us       17020                 :UBC           0 :                 pg_fatal("could not parse index statistic columns");
 1242 michael@paquier.xyz     17021         [ -  + ]:CBC          36 :             if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals))
  737 tgl@sss.pgh.pa.us       17022                 :UBC           0 :                 pg_fatal("could not parse index statistic values");
 1242 michael@paquier.xyz     17023         [ -  + ]:CBC          36 :             if (nstatcols != nstatvals)
  737 tgl@sss.pgh.pa.us       17024                 :UBC           0 :                 pg_fatal("mismatched number of columns and values for index statistics");
                              17025                 :                : 
 1944 michael@paquier.xyz     17026         [ +  + ]:CBC         108 :             for (j = 0; j < nstatcols; j++)
                              17027                 :                :             {
 1495 alvherre@alvh.no-ip.    17028                 :             72 :                 appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname);
                              17029                 :                : 
                              17030                 :                :                 /*
                              17031                 :                :                  * Note that this is a column number, so no quotes should be
                              17032                 :                :                  * used.
                              17033                 :                :                  */
 1944 michael@paquier.xyz     17034                 :             72 :                 appendPQExpBuffer(q, "ALTER COLUMN %s ",
                              17035                 :             72 :                                   indstatcolsarray[j]);
                              17036                 :             72 :                 appendPQExpBuffer(q, "SET STATISTICS %s;\n",
                              17037                 :             72 :                                   indstatvalsarray[j]);
                              17038                 :                :             }
                              17039                 :                :         }
                              17040                 :                : 
                              17041                 :                :         /* Indexes can depend on extensions */
 1495 alvherre@alvh.no-ip.    17042                 :            989 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              17043                 :                :                                     "pg_catalog.pg_class",
                              17044                 :                :                                     "INDEX", qqindxname);
                              17045                 :                : 
                              17046                 :                :         /* If the index defines identity, we need to record that. */
 3810 rhaas@postgresql.org    17047         [ -  + ]:            989 :         if (indxinfo->indisreplident)
                              17048                 :                :         {
 3810 rhaas@postgresql.org    17049                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
 2239 tgl@sss.pgh.pa.us       17050                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              17051                 :                :             /* index name is not qualified in this syntax */
 3810 rhaas@postgresql.org    17052                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              17053                 :                :                               qindxname);
                              17054                 :                :         }
                              17055                 :                : 
 1495 alvherre@alvh.no-ip.    17056                 :CBC         989 :         appendPQExpBuffer(delq, "DROP INDEX %s;\n", qqindxname);
                              17057                 :                : 
 2930 sfrost@snowman.net      17058         [ +  - ]:            989 :         if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17059                 :            989 :             ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17060                 :            989 :                          ARCHIVE_OPTS(.tag = indxinfo->dobj.name,
                              17061                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              17062                 :                :                                       .tablespace = indxinfo->tablespace,
                              17063                 :                :                                       .owner = tbinfo->rolname,
                              17064                 :                :                                       .description = "INDEX",
                              17065                 :                :                                       .section = SECTION_POST_DATA,
                              17066                 :                :                                       .createStmt = q->data,
                              17067                 :                :                                       .dropStmt = delq->data));
                              17068                 :                : 
  668 peter@eisentraut.org    17069                 :            989 :         free(indstatcolsarray);
                              17070                 :            989 :         free(indstatvalsarray);
                              17071                 :                :     }
                              17072                 :                : 
                              17073                 :                :     /* Dump Index Comments */
 2930 sfrost@snowman.net      17074         [ +  + ]:           2159 :     if (indxinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       17075         [ +  + ]:             15 :         dumpComment(fout, "INDEX", qindxname,
 2930 sfrost@snowman.net      17076                 :             15 :                     tbinfo->dobj.namespace->dobj.name,
                              17077                 :                :                     tbinfo->rolname,
                              17078                 :                :                     indxinfo->dobj.catId, 0,
                              17079                 :                :                     is_constraint ? indxinfo->indexconstraint :
                              17080                 :                :                     indxinfo->dobj.dumpId);
                              17081                 :                : 
 7435 tgl@sss.pgh.pa.us       17082                 :           2159 :     destroyPQExpBuffer(q);
                              17083                 :           2159 :     destroyPQExpBuffer(delq);
 2239                         17084                 :           2159 :     free(qindxname);
 1495 alvherre@alvh.no-ip.    17085                 :           2159 :     free(qqindxname);
                              17086                 :                : }
                              17087                 :                : 
                              17088                 :                : /*
                              17089                 :                :  * dumpIndexAttach
                              17090                 :                :  *    write out to fout a partitioned-index attachment clause
                              17091                 :                :  */
                              17092                 :                : static void
 1159 peter@eisentraut.org    17093                 :            567 : dumpIndexAttach(Archive *fout, const IndexAttachInfo *attachinfo)
                              17094                 :                : {
                              17095                 :                :     /* Do nothing in data-only dump */
 2277 alvherre@alvh.no-ip.    17096         [ +  + ]:            567 :     if (fout->dopt->dataOnly)
                              17097                 :             24 :         return;
                              17098                 :                : 
                              17099         [ +  - ]:            543 :     if (attachinfo->partitionIdx->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17100                 :                :     {
 2274 tgl@sss.pgh.pa.us       17101                 :            543 :         PQExpBuffer q = createPQExpBuffer();
                              17102                 :                : 
 2056                         17103                 :            543 :         appendPQExpBuffer(q, "ALTER INDEX %s ",
 2239                         17104                 :            543 :                           fmtQualifiedDumpable(attachinfo->parentIdx));
 2277 alvherre@alvh.no-ip.    17105                 :            543 :         appendPQExpBuffer(q, "ATTACH PARTITION %s;\n",
 2239 tgl@sss.pgh.pa.us       17106                 :            543 :                           fmtQualifiedDumpable(attachinfo->partitionIdx));
                              17107                 :                : 
                              17108                 :                :         /*
                              17109                 :                :          * There is no point in creating a drop query as the drop is done by
                              17110                 :                :          * index drop.  (If you think to change this, see also
                              17111                 :                :          * _printTocEntry().)  Although this object doesn't really have
                              17112                 :                :          * ownership as such, set the owner field anyway to ensure that the
                              17113                 :                :          * command is run by the correct role at restore time.
                              17114                 :                :          */
 2277 alvherre@alvh.no-ip.    17115                 :            543 :         ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId,
 1899                         17116                 :            543 :                      ARCHIVE_OPTS(.tag = attachinfo->dobj.name,
                              17117                 :                :                                   .namespace = attachinfo->dobj.namespace->dobj.name,
                              17118                 :                :                                   .owner = attachinfo->parentIdx->indextable->rolname,
                              17119                 :                :                                   .description = "INDEX ATTACH",
                              17120                 :                :                                   .section = SECTION_POST_DATA,
                              17121                 :                :                                   .createStmt = q->data));
                              17122                 :                : 
 2277                         17123                 :            543 :         destroyPQExpBuffer(q);
                              17124                 :                :     }
                              17125                 :                : }
                              17126                 :                : 
                              17127                 :                : /*
                              17128                 :                :  * dumpStatisticsExt
                              17129                 :                :  *    write out to fout an extended statistics object
                              17130                 :                :  */
                              17131                 :                : static void
 1159 peter@eisentraut.org    17132                 :            136 : dumpStatisticsExt(Archive *fout, const StatsExtInfo *statsextinfo)
                              17133                 :                : {
 2578 alvherre@alvh.no-ip.    17134                 :            136 :     DumpOptions *dopt = fout->dopt;
                              17135                 :                :     PQExpBuffer q;
                              17136                 :                :     PQExpBuffer delq;
                              17137                 :                :     PQExpBuffer query;
                              17138                 :                :     char       *qstatsextname;
                              17139                 :                :     PGresult   *res;
                              17140                 :                :     char       *stxdef;
                              17141                 :                : 
                              17142                 :                :     /* Do nothing in data-only dump */
  860 tgl@sss.pgh.pa.us       17143         [ +  + ]:            136 :     if (dopt->dataOnly)
 2578 alvherre@alvh.no-ip.    17144                 :              9 :         return;
                              17145                 :                : 
                              17146                 :            127 :     q = createPQExpBuffer();
                              17147                 :            127 :     delq = createPQExpBuffer();
 2254 tgl@sss.pgh.pa.us       17148                 :            127 :     query = createPQExpBuffer();
                              17149                 :                : 
 2239                         17150                 :            127 :     qstatsextname = pg_strdup(fmtId(statsextinfo->dobj.name));
                              17151                 :                : 
 2254                         17152                 :            127 :     appendPQExpBuffer(query, "SELECT "
                              17153                 :                :                       "pg_catalog.pg_get_statisticsobjdef('%u'::pg_catalog.oid)",
                              17154                 :            127 :                       statsextinfo->dobj.catId.oid);
                              17155                 :                : 
                              17156                 :            127 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              17157                 :                : 
                              17158                 :            127 :     stxdef = PQgetvalue(res, 0, 0);
                              17159                 :                : 
                              17160                 :                :     /* Result of pg_get_statisticsobjdef is complete except for semicolon */
                              17161                 :            127 :     appendPQExpBuffer(q, "%s;\n", stxdef);
                              17162                 :                : 
                              17163                 :                :     /*
                              17164                 :                :      * We only issue an ALTER STATISTICS statement if the stxstattarget entry
                              17165                 :                :      * for this statistics object is not the default value.
                              17166                 :                :      */
 1678 tomas.vondra@postgre    17167         [ +  + ]:            127 :     if (statsextinfo->stattarget >= 0)
                              17168                 :                :     {
                              17169                 :             36 :         appendPQExpBuffer(q, "ALTER STATISTICS %s ",
                              17170                 :             36 :                           fmtQualifiedDumpable(statsextinfo));
                              17171                 :             36 :         appendPQExpBuffer(q, "SET STATISTICS %d;\n",
                              17172                 :             36 :                           statsextinfo->stattarget);
                              17173                 :                :     }
                              17174                 :                : 
 2239 tgl@sss.pgh.pa.us       17175                 :            127 :     appendPQExpBuffer(delq, "DROP STATISTICS %s;\n",
                              17176                 :            127 :                       fmtQualifiedDumpable(statsextinfo));
                              17177                 :                : 
 2578 alvherre@alvh.no-ip.    17178         [ +  - ]:            127 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 2524 bruce@momjian.us        17179                 :            127 :         ArchiveEntry(fout, statsextinfo->dobj.catId,
                              17180                 :            127 :                      statsextinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17181                 :            127 :                      ARCHIVE_OPTS(.tag = statsextinfo->dobj.name,
                              17182                 :                :                                   .namespace = statsextinfo->dobj.namespace->dobj.name,
                              17183                 :                :                                   .owner = statsextinfo->rolname,
                              17184                 :                :                                   .description = "STATISTICS",
                              17185                 :                :                                   .section = SECTION_POST_DATA,
                              17186                 :                :                                   .createStmt = q->data,
                              17187                 :                :                                   .dropStmt = delq->data));
                              17188                 :                : 
                              17189                 :                :     /* Dump Statistics Comments */
 2578                         17190         [ -  + ]:            127 :     if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       17191                 :UBC           0 :         dumpComment(fout, "STATISTICS", qstatsextname,
 2254                         17192                 :              0 :                     statsextinfo->dobj.namespace->dobj.name,
                              17193                 :              0 :                     statsextinfo->rolname,
                              17194                 :                :                     statsextinfo->dobj.catId, 0,
 2578 alvherre@alvh.no-ip.    17195                 :              0 :                     statsextinfo->dobj.dumpId);
                              17196                 :                : 
 2254 tgl@sss.pgh.pa.us       17197                 :CBC         127 :     PQclear(res);
 2578 alvherre@alvh.no-ip.    17198                 :            127 :     destroyPQExpBuffer(q);
                              17199                 :            127 :     destroyPQExpBuffer(delq);
 2254 tgl@sss.pgh.pa.us       17200                 :            127 :     destroyPQExpBuffer(query);
 2239                         17201                 :            127 :     free(qstatsextname);
                              17202                 :                : }
                              17203                 :                : 
                              17204                 :                : /*
                              17205                 :                :  * dumpConstraint
                              17206                 :                :  *    write out to fout a user-defined constraint
                              17207                 :                :  */
                              17208                 :                : static void
 1159 peter@eisentraut.org    17209                 :           2033 : dumpConstraint(Archive *fout, const ConstraintInfo *coninfo)
                              17210                 :                : {
 3014 tgl@sss.pgh.pa.us       17211                 :           2033 :     DumpOptions *dopt = fout->dopt;
 7435                         17212                 :           2033 :     TableInfo  *tbinfo = coninfo->contable;
                              17213                 :                :     PQExpBuffer q;
                              17214                 :                :     PQExpBuffer delq;
 2971 peter_e@gmx.net         17215                 :           2033 :     char       *tag = NULL;
                              17216                 :                :     char       *foreign;
                              17217                 :                : 
                              17218                 :                :     /* Do nothing in data-only dump */
  860 tgl@sss.pgh.pa.us       17219         [ +  + ]:           2033 :     if (dopt->dataOnly)
 7435                         17220                 :             47 :         return;
                              17221                 :                : 
                              17222                 :           1986 :     q = createPQExpBuffer();
                              17223                 :           1986 :     delq = createPQExpBuffer();
                              17224                 :                : 
 1486 alvherre@alvh.no-ip.    17225                 :           3886 :     foreign = tbinfo &&
 1431 tgl@sss.pgh.pa.us       17226   [ +  +  -  + ]:           1986 :         tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "";
                              17227                 :                : 
 5242                         17228         [ +  + ]:           1986 :     if (coninfo->contype == 'p' ||
                              17229         [ +  + ]:            958 :         coninfo->contype == 'u' ||
                              17230         [ +  + ]:            826 :         coninfo->contype == 'x')
 7435                         17231                 :           1170 :     {
                              17232                 :                :         /* Index-related constraint */
                              17233                 :                :         IndxInfo   *indxinfo;
                              17234                 :                :         int         k;
                              17235                 :                : 
                              17236                 :           1170 :         indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
                              17237                 :                : 
                              17238         [ -  + ]:           1170 :         if (indxinfo == NULL)
  737 tgl@sss.pgh.pa.us       17239                 :UBC           0 :             pg_fatal("missing index for constraint \"%s\"",
                              17240                 :                :                      coninfo->dobj.name);
                              17241                 :                : 
 3470 alvherre@alvh.no-ip.    17242         [ +  + ]:CBC        1170 :         if (dopt->binary_upgrade)
 4450 rhaas@postgresql.org    17243                 :            130 :             binary_upgrade_set_pg_class_oids(fout, q,
                              17244                 :                :                                              indxinfo->dobj.catId.oid, true);
                              17245                 :                : 
 1486 alvherre@alvh.no-ip.    17246                 :           1170 :         appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s\n", foreign,
 2239 tgl@sss.pgh.pa.us       17247                 :           1170 :                           fmtQualifiedDumpable(tbinfo));
 5242                         17248                 :           1170 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s ",
                              17249                 :           1170 :                           fmtId(coninfo->dobj.name));
                              17250                 :                : 
                              17251         [ +  + ]:           1170 :         if (coninfo->condef)
                              17252                 :                :         {
                              17253                 :                :             /* pg_get_constraintdef should have provided everything */
                              17254                 :             10 :             appendPQExpBuffer(q, "%s;\n", coninfo->condef);
                              17255                 :                :         }
                              17256                 :                :         else
                              17257                 :                :         {
  586 drowley@postgresql.o    17258                 :           1160 :             appendPQExpBufferStr(q,
                              17259         [ +  + ]:           1160 :                                  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
                              17260                 :                : 
                              17261                 :                :             /*
                              17262                 :                :              * PRIMARY KEY constraints should not be using NULLS NOT DISTINCT
                              17263                 :                :              * indexes. Being able to create this was fixed, but we need to
                              17264                 :                :              * make the index distinct in order to be able to restore the
                              17265                 :                :              * dump.
                              17266                 :                :              */
  415 dgustafsson@postgres    17267   [ -  +  -  - ]:           1160 :             if (indxinfo->indnullsnotdistinct && coninfo->contype != 'p')
  586 drowley@postgresql.o    17268                 :UBC           0 :                 appendPQExpBufferStr(q, " NULLS NOT DISTINCT");
  586 drowley@postgresql.o    17269                 :CBC        1160 :             appendPQExpBufferStr(q, " (");
 2199 teodor@sigaev.ru        17270         [ +  + ]:           2798 :             for (k = 0; k < indxinfo->indnkeyattrs; k++)
                              17271                 :                :             {
 5242 tgl@sss.pgh.pa.us       17272                 :           1638 :                 int         indkey = (int) indxinfo->indkeys[k];
                              17273                 :                :                 const char *attname;
                              17274                 :                : 
                              17275         [ -  + ]:           1638 :                 if (indkey == InvalidAttrNumber)
 5242 tgl@sss.pgh.pa.us       17276                 :UBC           0 :                     break;
 5242 tgl@sss.pgh.pa.us       17277                 :CBC        1638 :                 attname = getAttrName(indkey, tbinfo);
                              17278                 :                : 
                              17279         [ +  + ]:           1638 :                 appendPQExpBuffer(q, "%s%s",
                              17280                 :                :                                   (k == 0) ? "" : ", ",
                              17281                 :                :                                   fmtId(attname));
                              17282                 :                :             }
   40 peter@eisentraut.org    17283         [ +  + ]:GNC        1160 :             if (coninfo->conperiod)
   81                         17284                 :            117 :                 appendPQExpBufferStr(q, " WITHOUT OVERLAPS");
                              17285                 :                : 
 2199 teodor@sigaev.ru        17286         [ +  + ]:CBC        1160 :             if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
 1746 drowley@postgresql.o    17287                 :             20 :                 appendPQExpBufferStr(q, ") INCLUDE (");
                              17288                 :                : 
 2199 teodor@sigaev.ru        17289         [ +  + ]:           1200 :             for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
                              17290                 :                :             {
                              17291                 :             40 :                 int         indkey = (int) indxinfo->indkeys[k];
                              17292                 :                :                 const char *attname;
                              17293                 :                : 
                              17294         [ -  + ]:             40 :                 if (indkey == InvalidAttrNumber)
 2199 teodor@sigaev.ru        17295                 :UBC           0 :                     break;
 2199 teodor@sigaev.ru        17296                 :CBC          40 :                 attname = getAttrName(indkey, tbinfo);
                              17297                 :                : 
                              17298                 :             80 :                 appendPQExpBuffer(q, "%s%s",
                              17299         [ +  + ]:             40 :                                   (k == indxinfo->indnkeyattrs) ? "" : ", ",
                              17300                 :                :                                   fmtId(attname));
                              17301                 :                :             }
                              17302                 :                : 
 3800 heikki.linnakangas@i    17303                 :           1160 :             appendPQExpBufferChar(q, ')');
                              17304                 :                : 
 3025 tgl@sss.pgh.pa.us       17305         [ -  + ]:           1160 :             if (nonemptyReloptions(indxinfo->indreloptions))
                              17306                 :                :             {
 3025 tgl@sss.pgh.pa.us       17307                 :UBC           0 :                 appendPQExpBufferStr(q, " WITH (");
 2900 dean.a.rasheed@gmail    17308                 :              0 :                 appendReloptionsArrayAH(q, indxinfo->indreloptions, "", fout);
 3025 tgl@sss.pgh.pa.us       17309                 :              0 :                 appendPQExpBufferChar(q, ')');
                              17310                 :                :             }
                              17311                 :                : 
 5242 tgl@sss.pgh.pa.us       17312         [ +  + ]:CBC        1160 :             if (coninfo->condeferrable)
                              17313                 :                :             {
 3800 heikki.linnakangas@i    17314                 :GBC          25 :                 appendPQExpBufferStr(q, " DEFERRABLE");
 5242 tgl@sss.pgh.pa.us       17315         [ +  + ]:             25 :                 if (coninfo->condeferred)
 3800 heikki.linnakangas@i    17316                 :             15 :                     appendPQExpBufferStr(q, " INITIALLY DEFERRED");
                              17317                 :                :             }
                              17318                 :                : 
 3800 heikki.linnakangas@i    17319                 :CBC        1160 :             appendPQExpBufferStr(q, ";\n");
                              17320                 :                :         }
                              17321                 :                : 
                              17322                 :                :         /*
                              17323                 :                :          * Append ALTER TABLE commands as needed to set properties that we
                              17324                 :                :          * only have ALTER TABLE syntax for.  Keep this in sync with the
                              17325                 :                :          * similar code in dumpIndex!
                              17326                 :                :          */
                              17327                 :                : 
                              17328                 :                :         /* Drop any not-null constraints that were added to support the PK */
  233 alvherre@alvh.no-ip.    17329         [ +  + ]:GNC        1170 :         if (coninfo->contype == 'p')
                              17330         [ +  + ]:           3909 :             for (int i = 0; i < tbinfo->numatts; i++)
                              17331         [ +  + ]:           2881 :                 if (tbinfo->notnull_throwaway[i])
                              17332                 :            803 :                     appendPQExpBuffer(q, "\nALTER TABLE ONLY %s DROP CONSTRAINT %s;",
                              17333                 :            803 :                                       fmtQualifiedDumpable(tbinfo),
                              17334                 :            803 :                                       tbinfo->notnull_constrs[i]);
                              17335                 :                : 
                              17336                 :                :         /* If the index is clustered, we need to record that. */
 7435 tgl@sss.pgh.pa.us       17337         [ +  + ]:CBC        1170 :         if (indxinfo->indisclustered)
                              17338                 :                :         {
                              17339                 :             36 :             appendPQExpBuffer(q, "\nALTER TABLE %s CLUSTER",
 2239                         17340                 :             36 :                               fmtQualifiedDumpable(tbinfo));
                              17341                 :                :             /* index name is not qualified in this syntax */
 7435                         17342                 :             36 :             appendPQExpBuffer(q, " ON %s;\n",
 7347                         17343                 :             36 :                               fmtId(indxinfo->dobj.name));
                              17344                 :                :         }
                              17345                 :                : 
                              17346                 :                :         /* If the index defines identity, we need to record that. */
 2085                         17347         [ -  + ]:           1170 :         if (indxinfo->indisreplident)
                              17348                 :                :         {
 2085 tgl@sss.pgh.pa.us       17349                 :UBC           0 :             appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
                              17350                 :              0 :                               fmtQualifiedDumpable(tbinfo));
                              17351                 :                :             /* index name is not qualified in this syntax */
                              17352                 :              0 :             appendPQExpBuffer(q, " INDEX %s;\n",
                              17353                 :              0 :                               fmtId(indxinfo->dobj.name));
                              17354                 :                :         }
                              17355                 :                : 
                              17356                 :                :         /* Indexes can depend on extensions */
 1495 alvherre@alvh.no-ip.    17357                 :CBC        1170 :         append_depends_on_extension(fout, q, &indxinfo->dobj,
                              17358                 :                :                                     "pg_catalog.pg_class", "INDEX",
                              17359                 :           1170 :                                     fmtQualifiedDumpable(indxinfo));
                              17360                 :                : 
 1486                         17361                 :           1170 :         appendPQExpBuffer(delq, "ALTER %sTABLE ONLY %s ", foreign,
 2239 tgl@sss.pgh.pa.us       17362                 :           1170 :                           fmtQualifiedDumpable(tbinfo));
 7435                         17363                 :           1170 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7347                         17364                 :           1170 :                           fmtId(coninfo->dobj.name));
                              17365                 :                : 
 2971 peter_e@gmx.net         17366                 :           1170 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              17367                 :                : 
 2930 sfrost@snowman.net      17368         [ +  - ]:           1170 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17369                 :           1170 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17370                 :           1170 :                          ARCHIVE_OPTS(.tag = tag,
                              17371                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              17372                 :                :                                       .tablespace = indxinfo->tablespace,
                              17373                 :                :                                       .owner = tbinfo->rolname,
                              17374                 :                :                                       .description = "CONSTRAINT",
                              17375                 :                :                                       .section = SECTION_POST_DATA,
                              17376                 :                :                                       .createStmt = q->data,
                              17377                 :                :                                       .dropStmt = delq->data));
                              17378                 :                :     }
 7435 tgl@sss.pgh.pa.us       17379         [ +  + ]:            816 :     else if (coninfo->contype == 'f')
                              17380                 :                :     {
                              17381                 :                :         char       *only;
                              17382                 :                : 
                              17383                 :                :         /*
                              17384                 :                :          * Foreign keys on partitioned tables are always declared as
                              17385                 :                :          * inheriting to partitions; for all other cases, emit them as
                              17386                 :                :          * applying ONLY directly to the named table, because that's how they
                              17387                 :                :          * work for regular inherited tables.
                              17388                 :                :          */
 2202 alvherre@alvh.no-ip.    17389         [ +  + ]:            172 :         only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY ";
                              17390                 :                : 
                              17391                 :                :         /*
                              17392                 :                :          * XXX Potentially wrap in a 'SET CONSTRAINTS OFF' block so that the
                              17393                 :                :          * current table data is not processed
                              17394                 :                :          */
 1486                         17395                 :            172 :         appendPQExpBuffer(q, "ALTER %sTABLE %s%s\n", foreign,
 2202                         17396                 :            172 :                           only, fmtQualifiedDumpable(tbinfo));
 7435 tgl@sss.pgh.pa.us       17397                 :            172 :         appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7347                         17398                 :            172 :                           fmtId(coninfo->dobj.name),
 7435                         17399                 :            172 :                           coninfo->condef);
                              17400                 :                : 
 1486 alvherre@alvh.no-ip.    17401                 :            172 :         appendPQExpBuffer(delq, "ALTER %sTABLE %s%s ", foreign,
 2202                         17402                 :            172 :                           only, fmtQualifiedDumpable(tbinfo));
 7435 tgl@sss.pgh.pa.us       17403                 :            172 :         appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7347                         17404                 :            172 :                           fmtId(coninfo->dobj.name));
                              17405                 :                : 
 2971 peter_e@gmx.net         17406                 :            172 :         tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              17407                 :                : 
 2930 sfrost@snowman.net      17408         [ +  - ]:            172 :         if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17409                 :            172 :             ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17410                 :            172 :                          ARCHIVE_OPTS(.tag = tag,
                              17411                 :                :                                       .namespace = tbinfo->dobj.namespace->dobj.name,
                              17412                 :                :                                       .owner = tbinfo->rolname,
                              17413                 :                :                                       .description = "FK CONSTRAINT",
                              17414                 :                :                                       .section = SECTION_POST_DATA,
                              17415                 :                :                                       .createStmt = q->data,
                              17416                 :                :                                       .dropStmt = delq->data));
                              17417                 :                :     }
 7435 tgl@sss.pgh.pa.us       17418   [ +  -  +  + ]:            644 :     else if (coninfo->contype == 'c' && tbinfo)
                              17419                 :                :     {
                              17420                 :                :         /* CHECK constraint on a table */
                              17421                 :                : 
                              17422                 :                :         /* Ignore if not to be dumped separately, or if it was inherited */
 3118                         17423   [ +  +  +  + ]:            558 :         if (coninfo->separate && coninfo->conislocal)
                              17424                 :                :         {
                              17425                 :                :             /* not ONLY since we want it to propagate to children */
 1486 alvherre@alvh.no-ip.    17426                 :             25 :             appendPQExpBuffer(q, "ALTER %sTABLE %s\n", foreign,
 2239 tgl@sss.pgh.pa.us       17427                 :             25 :                               fmtQualifiedDumpable(tbinfo));
 7435                         17428                 :             25 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7347                         17429                 :             25 :                               fmtId(coninfo->dobj.name),
 7435                         17430                 :             25 :                               coninfo->condef);
                              17431                 :                : 
 1486 alvherre@alvh.no-ip.    17432                 :             25 :             appendPQExpBuffer(delq, "ALTER %sTABLE %s ", foreign,
 2239 tgl@sss.pgh.pa.us       17433                 :             25 :                               fmtQualifiedDumpable(tbinfo));
 7435                         17434                 :             25 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7347                         17435                 :             25 :                               fmtId(coninfo->dobj.name));
                              17436                 :                : 
 2971 peter_e@gmx.net         17437                 :             25 :             tag = psprintf("%s %s", tbinfo->dobj.name, coninfo->dobj.name);
                              17438                 :                : 
 2930 sfrost@snowman.net      17439         [ +  - ]:             25 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17440                 :             25 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17441                 :             25 :                              ARCHIVE_OPTS(.tag = tag,
                              17442                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              17443                 :                :                                           .owner = tbinfo->rolname,
                              17444                 :                :                                           .description = "CHECK CONSTRAINT",
                              17445                 :                :                                           .section = SECTION_POST_DATA,
                              17446                 :                :                                           .createStmt = q->data,
                              17447                 :                :                                           .dropStmt = delq->data));
                              17448                 :                :         }
                              17449                 :                :     }
 7435 tgl@sss.pgh.pa.us       17450   [ +  -  +  - ]:             86 :     else if (coninfo->contype == 'c' && tbinfo == NULL)
                              17451                 :             86 :     {
                              17452                 :                :         /* CHECK constraint on a domain */
 5226 bruce@momjian.us        17453                 :             86 :         TypeInfo   *tyinfo = coninfo->condomain;
                              17454                 :                : 
                              17455                 :                :         /* Ignore if not to be dumped separately */
 6618 tgl@sss.pgh.pa.us       17456         [ -  + ]:             86 :         if (coninfo->separate)
                              17457                 :                :         {
 7435 tgl@sss.pgh.pa.us       17458                 :UBC           0 :             appendPQExpBuffer(q, "ALTER DOMAIN %s\n",
 2239                         17459                 :              0 :                               fmtQualifiedDumpable(tyinfo));
 7435                         17460                 :              0 :             appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
 7347                         17461                 :              0 :                               fmtId(coninfo->dobj.name),
 7435                         17462                 :              0 :                               coninfo->condef);
                              17463                 :                : 
 2239                         17464                 :              0 :             appendPQExpBuffer(delq, "ALTER DOMAIN %s ",
                              17465                 :              0 :                               fmtQualifiedDumpable(tyinfo));
 7435                         17466                 :              0 :             appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n",
 7347                         17467                 :              0 :                               fmtId(coninfo->dobj.name));
                              17468                 :                : 
 2971 peter_e@gmx.net         17469                 :              0 :             tag = psprintf("%s %s", tyinfo->dobj.name, coninfo->dobj.name);
                              17470                 :                : 
 2930 sfrost@snowman.net      17471         [ #  # ]:              0 :             if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17472                 :              0 :                 ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17473                 :              0 :                              ARCHIVE_OPTS(.tag = tag,
                              17474                 :                :                                           .namespace = tyinfo->dobj.namespace->dobj.name,
                              17475                 :                :                                           .owner = tyinfo->rolname,
                              17476                 :                :                                           .description = "CHECK CONSTRAINT",
                              17477                 :                :                                           .section = SECTION_POST_DATA,
                              17478                 :                :                                           .createStmt = q->data,
                              17479                 :                :                                           .dropStmt = delq->data));
                              17480                 :                :         }
                              17481                 :                :     }
                              17482                 :                :     else
                              17483                 :                :     {
  737 tgl@sss.pgh.pa.us       17484                 :              0 :         pg_fatal("unrecognized constraint type: %c",
                              17485                 :                :                  coninfo->contype);
                              17486                 :                :     }
                              17487                 :                : 
                              17488                 :                :     /* Dump Constraint Comments --- only works for table constraints */
 2930 sfrost@snowman.net      17489   [ +  +  +  + ]:CBC        1986 :     if (tbinfo && coninfo->separate &&
                              17490         [ +  + ]:           1382 :         coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 3014 tgl@sss.pgh.pa.us       17491                 :             10 :         dumpTableConstraintComment(fout, coninfo);
                              17492                 :                : 
 2971 peter_e@gmx.net         17493                 :           1986 :     free(tag);
 8010 tgl@sss.pgh.pa.us       17494                 :           1986 :     destroyPQExpBuffer(q);
                              17495                 :           1986 :     destroyPQExpBuffer(delq);
                              17496                 :                : }
                              17497                 :                : 
                              17498                 :                : /*
                              17499                 :                :  * dumpTableConstraintComment --- dump a constraint's comment if any
                              17500                 :                :  *
                              17501                 :                :  * This is split out because we need the function in two different places
                              17502                 :                :  * depending on whether the constraint is dumped as part of CREATE TABLE
                              17503                 :                :  * or as a separate ALTER command.
                              17504                 :                :  */
                              17505                 :                : static void
 1159 peter@eisentraut.org    17506                 :             51 : dumpTableConstraintComment(Archive *fout, const ConstraintInfo *coninfo)
                              17507                 :                : {
 7061 tgl@sss.pgh.pa.us       17508                 :             51 :     TableInfo  *tbinfo = coninfo->contable;
 2239                         17509                 :             51 :     PQExpBuffer conprefix = createPQExpBuffer();
                              17510                 :                :     char       *qtabname;
                              17511                 :                : 
                              17512                 :             51 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              17513                 :                : 
                              17514                 :             51 :     appendPQExpBuffer(conprefix, "CONSTRAINT %s ON",
 7061                         17515                 :             51 :                       fmtId(coninfo->dobj.name));
                              17516                 :                : 
 2930 sfrost@snowman.net      17517         [ +  - ]:             51 :     if (coninfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       17518                 :             51 :         dumpComment(fout, conprefix->data, qtabname,
 2930 sfrost@snowman.net      17519                 :             51 :                     tbinfo->dobj.namespace->dobj.name,
                              17520                 :                :                     tbinfo->rolname,
                              17521                 :                :                     coninfo->dobj.catId, 0,
 2489 tgl@sss.pgh.pa.us       17522         [ +  + ]:             51 :                     coninfo->separate ? coninfo->dobj.dumpId : tbinfo->dobj.dumpId);
                              17523                 :                : 
 2239                         17524                 :             51 :     destroyPQExpBuffer(conprefix);
                              17525                 :             51 :     free(qtabname);
 7061                         17526                 :             51 : }
                              17527                 :                : 
                              17528                 :                : /*
                              17529                 :                :  * dumpSequence
                              17530                 :                :  *    write the declaration (not data) of one user-defined sequence
                              17531                 :                :  */
                              17532                 :                : static void
 1159 peter@eisentraut.org    17533                 :            367 : dumpSequence(Archive *fout, const TableInfo *tbinfo)
                              17534                 :                : {
 3014 tgl@sss.pgh.pa.us       17535                 :            367 :     DumpOptions *dopt = fout->dopt;
                              17536                 :                :     PGresult   *res;
                              17537                 :                :     char       *startv,
                              17538                 :                :                *incby,
                              17539                 :                :                *maxv,
                              17540                 :                :                *minv,
                              17541                 :                :                *cache,
                              17542                 :                :                *seqtype;
                              17543                 :                :     bool        cycled;
                              17544                 :                :     bool        is_ascending;
                              17545                 :                :     int64       default_minv,
                              17546                 :                :                 default_maxv;
                              17547                 :                :     char        bufm[32],
                              17548                 :                :                 bufx[32];
 8768 bruce@momjian.us        17549                 :            367 :     PQExpBuffer query = createPQExpBuffer();
 8685                         17550                 :            367 :     PQExpBuffer delqry = createPQExpBuffer();
                              17551                 :                :     char       *qseqname;
  738 peter@eisentraut.org    17552                 :            367 :     TableInfo  *owning_tab = NULL;
                              17553                 :                : 
 2239 tgl@sss.pgh.pa.us       17554                 :            367 :     qseqname = pg_strdup(fmtId(tbinfo->dobj.name));
                              17555                 :                : 
 2672 peter_e@gmx.net         17556         [ +  - ]:            367 :     if (fout->remoteVersion >= 100000)
                              17557                 :                :     {
                              17558                 :            367 :         appendPQExpBuffer(query,
                              17559                 :                :                           "SELECT format_type(seqtypid, NULL), "
                              17560                 :                :                           "seqstart, seqincrement, "
                              17561                 :                :                           "seqmax, seqmin, "
                              17562                 :                :                           "seqcache, seqcycle "
                              17563                 :                :                           "FROM pg_catalog.pg_sequence "
                              17564                 :                :                           "WHERE seqrelid = '%u'::oid",
 2637                         17565                 :            367 :                           tbinfo->dobj.catId.oid);
                              17566                 :                :     }
                              17567                 :                :     else
                              17568                 :                :     {
                              17569                 :                :         /*
                              17570                 :                :          * Before PostgreSQL 10, sequence metadata is in the sequence itself.
                              17571                 :                :          *
                              17572                 :                :          * Note: it might seem that 'bigint' potentially needs to be
                              17573                 :                :          * schema-qualified, but actually that's a keyword.
                              17574                 :                :          */
 5812 tgl@sss.pgh.pa.us       17575                 :UBC           0 :         appendPQExpBuffer(query,
                              17576                 :                :                           "SELECT 'bigint' AS sequence_type, "
                              17577                 :                :                           "start_value, increment_by, max_value, min_value, "
                              17578                 :                :                           "cache_value, is_cycled FROM %s",
 2239                         17579                 :              0 :                           fmtQualifiedDumpable(tbinfo));
                              17580                 :                :     }
                              17581                 :                : 
 4450 rhaas@postgresql.org    17582                 :CBC         367 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              17583                 :                : 
 9716 bruce@momjian.us        17584         [ -  + ]:            367 :     if (PQntuples(res) != 1)
  737 tgl@sss.pgh.pa.us       17585                 :UBC           0 :         pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              17586                 :                :                           "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              17587                 :                :                           PQntuples(res)),
                              17588                 :                :                  tbinfo->dobj.name, PQntuples(res));
                              17589                 :                : 
 2620 peter_e@gmx.net         17590                 :CBC         367 :     seqtype = PQgetvalue(res, 0, 0);
                              17591                 :            367 :     startv = PQgetvalue(res, 0, 1);
                              17592                 :            367 :     incby = PQgetvalue(res, 0, 2);
                              17593                 :            367 :     maxv = PQgetvalue(res, 0, 3);
                              17594                 :            367 :     minv = PQgetvalue(res, 0, 4);
                              17595                 :            367 :     cache = PQgetvalue(res, 0, 5);
                              17596                 :            367 :     cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
                              17597                 :                : 
                              17598                 :                :     /* Calculate default limits for a sequence of this type */
 2245 tgl@sss.pgh.pa.us       17599                 :            367 :     is_ascending = (incby[0] != '-');
 2620 peter_e@gmx.net         17600         [ +  + ]:            367 :     if (strcmp(seqtype, "smallint") == 0)
                              17601                 :                :     {
 2245 tgl@sss.pgh.pa.us       17602         [ +  + ]:             25 :         default_minv = is_ascending ? 1 : PG_INT16_MIN;
                              17603         [ +  + ]:             25 :         default_maxv = is_ascending ? PG_INT16_MAX : -1;
                              17604                 :                :     }
 2620 peter_e@gmx.net         17605         [ +  + ]:            342 :     else if (strcmp(seqtype, "integer") == 0)
                              17606                 :                :     {
 2245 tgl@sss.pgh.pa.us       17607         [ +  + ]:            286 :         default_minv = is_ascending ? 1 : PG_INT32_MIN;
                              17608         [ +  + ]:            286 :         default_maxv = is_ascending ? PG_INT32_MAX : -1;
                              17609                 :                :     }
 2620 peter_e@gmx.net         17610         [ +  - ]:             56 :     else if (strcmp(seqtype, "bigint") == 0)
                              17611                 :                :     {
 2245 tgl@sss.pgh.pa.us       17612         [ +  + ]:             56 :         default_minv = is_ascending ? 1 : PG_INT64_MIN;
                              17613         [ +  + ]:             56 :         default_maxv = is_ascending ? PG_INT64_MAX : -1;
                              17614                 :                :     }
                              17615                 :                :     else
                              17616                 :                :     {
  737 tgl@sss.pgh.pa.us       17617                 :UBC           0 :         pg_fatal("unrecognized sequence type: %s", seqtype);
                              17618                 :                :         default_minv = default_maxv = 0;    /* keep compiler quiet */
                              17619                 :                :     }
                              17620                 :                : 
                              17621                 :                :     /*
                              17622                 :                :      * 64-bit strtol() isn't very portable, so convert the limits to strings
                              17623                 :                :      * and compare that way.
                              17624                 :                :      */
 2245 tgl@sss.pgh.pa.us       17625                 :CBC         367 :     snprintf(bufm, sizeof(bufm), INT64_FORMAT, default_minv);
                              17626                 :            367 :     snprintf(bufx, sizeof(bufx), INT64_FORMAT, default_maxv);
                              17627                 :                : 
                              17628                 :                :     /* Don't print minv/maxv if they match the respective default limit */
                              17629         [ +  + ]:            367 :     if (strcmp(minv, bufm) == 0)
                              17630                 :            352 :         minv = NULL;
                              17631         [ +  + ]:            367 :     if (strcmp(maxv, bufx) == 0)
                              17632                 :            352 :         maxv = NULL;
                              17633                 :                : 
                              17634                 :                :     /*
                              17635                 :                :      * Identity sequences are not to be dropped separately.
                              17636                 :                :      */
 2565 peter_e@gmx.net         17637         [ +  + ]:            367 :     if (!tbinfo->is_identity_sequence)
                              17638                 :                :     {
 2239 tgl@sss.pgh.pa.us       17639                 :            236 :         appendPQExpBuffer(delqry, "DROP SEQUENCE %s;\n",
                              17640                 :            236 :                           fmtQualifiedDumpable(tbinfo));
                              17641                 :                :     }
                              17642                 :                : 
 4188                         17643                 :            367 :     resetPQExpBuffer(query);
                              17644                 :                : 
 3470 alvherre@alvh.no-ip.    17645         [ +  + ]:            367 :     if (dopt->binary_upgrade)
                              17646                 :                :     {
 4188 tgl@sss.pgh.pa.us       17647                 :             58 :         binary_upgrade_set_pg_class_oids(fout, query,
                              17648                 :             58 :                                          tbinfo->dobj.catId.oid, false);
                              17649                 :                : 
                              17650                 :                :         /*
                              17651                 :                :          * In older PG versions a sequence will have a pg_type entry, but v14
                              17652                 :                :          * and up don't use that, so don't attempt to preserve the type OID.
                              17653                 :                :          */
                              17654                 :                :     }
                              17655                 :                : 
 2565 peter_e@gmx.net         17656         [ +  + ]:            367 :     if (tbinfo->is_identity_sequence)
                              17657                 :                :     {
  738 peter@eisentraut.org    17658                 :            131 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              17659                 :                : 
 2565 peter_e@gmx.net         17660                 :            131 :         appendPQExpBuffer(query,
                              17661                 :                :                           "ALTER TABLE %s ",
 2239 tgl@sss.pgh.pa.us       17662                 :            131 :                           fmtQualifiedDumpable(owning_tab));
 2565 peter_e@gmx.net         17663                 :            131 :         appendPQExpBuffer(query,
                              17664                 :                :                           "ALTER COLUMN %s ADD GENERATED ",
 2489 tgl@sss.pgh.pa.us       17665                 :            131 :                           fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
 2565 peter_e@gmx.net         17666         [ +  + ]:            131 :         if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS)
 1746 drowley@postgresql.o    17667                 :             91 :             appendPQExpBufferStr(query, "ALWAYS");
 2565 peter_e@gmx.net         17668         [ +  - ]:             40 :         else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT)
 1746 drowley@postgresql.o    17669                 :             40 :             appendPQExpBufferStr(query, "BY DEFAULT");
 2565 peter_e@gmx.net         17670                 :            131 :         appendPQExpBuffer(query, " AS IDENTITY (\n    SEQUENCE NAME %s\n",
 2239 tgl@sss.pgh.pa.us       17671                 :            131 :                           fmtQualifiedDumpable(tbinfo));
                              17672                 :                :     }
                              17673                 :                :     else
                              17674                 :                :     {
 2565 peter_e@gmx.net         17675                 :            236 :         appendPQExpBuffer(query,
                              17676                 :                :                           "CREATE %sSEQUENCE %s\n",
  738 peter@eisentraut.org    17677         [ +  + ]:            236 :                           tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              17678                 :                :                           "UNLOGGED " : "",
 2239 tgl@sss.pgh.pa.us       17679                 :            236 :                           fmtQualifiedDumpable(tbinfo));
                              17680                 :                : 
 2565 peter_e@gmx.net         17681         [ +  + ]:            236 :         if (strcmp(seqtype, "bigint") != 0)
                              17682                 :            190 :             appendPQExpBuffer(query, "    AS %s\n", seqtype);
                              17683                 :                :     }
                              17684                 :                : 
  852 tgl@sss.pgh.pa.us       17685                 :            367 :     appendPQExpBuffer(query, "    START WITH %s\n", startv);
                              17686                 :                : 
 4188                         17687                 :            367 :     appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
                              17688                 :                : 
                              17689         [ +  + ]:            367 :     if (minv)
                              17690                 :             15 :         appendPQExpBuffer(query, "    MINVALUE %s\n", minv);
                              17691                 :                :     else
 3800 heikki.linnakangas@i    17692                 :            352 :         appendPQExpBufferStr(query, "    NO MINVALUE\n");
                              17693                 :                : 
 4188 tgl@sss.pgh.pa.us       17694         [ +  + ]:            367 :     if (maxv)
                              17695                 :             15 :         appendPQExpBuffer(query, "    MAXVALUE %s\n", maxv);
                              17696                 :                :     else
 3800 heikki.linnakangas@i    17697                 :            352 :         appendPQExpBufferStr(query, "    NO MAXVALUE\n");
                              17698                 :                : 
 4188 tgl@sss.pgh.pa.us       17699         [ +  + ]:            367 :     appendPQExpBuffer(query,
                              17700                 :                :                       "    CACHE %s%s",
                              17701                 :                :                       cache, (cycled ? "\n    CYCLE" : ""));
                              17702                 :                : 
 2565 peter_e@gmx.net         17703         [ +  + ]:            367 :     if (tbinfo->is_identity_sequence)
                              17704                 :                :     {
                              17705                 :            131 :         appendPQExpBufferStr(query, "\n);\n");
  738 peter@eisentraut.org    17706         [ -  + ]:            131 :         if (tbinfo->relpersistence != owning_tab->relpersistence)
  738 peter@eisentraut.org    17707                 :UBC           0 :             appendPQExpBuffer(query,
                              17708                 :                :                               "ALTER SEQUENCE %s SET %s;\n",
                              17709                 :              0 :                               fmtQualifiedDumpable(tbinfo),
                              17710         [ #  # ]:              0 :                               tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
                              17711                 :                :                               "UNLOGGED" : "LOGGED");
                              17712                 :                :     }
                              17713                 :                :     else
 2565 peter_e@gmx.net         17714                 :CBC         236 :         appendPQExpBufferStr(query, ";\n");
                              17715                 :                : 
                              17716                 :                :     /* binary_upgrade:  no need to clear TOAST table oid */
                              17717                 :                : 
 3470 alvherre@alvh.no-ip.    17718         [ +  + ]:            367 :     if (dopt->binary_upgrade)
 4188 tgl@sss.pgh.pa.us       17719                 :             58 :         binary_upgrade_extension_member(query, &tbinfo->dobj,
                              17720                 :                :                                         "SEQUENCE", qseqname,
 2239                         17721                 :             58 :                                         tbinfo->dobj.namespace->dobj.name);
                              17722                 :                : 
 2930 sfrost@snowman.net      17723         [ +  - ]:            367 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17724                 :            367 :         ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17725                 :            367 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              17726                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              17727                 :                :                                   .owner = tbinfo->rolname,
                              17728                 :                :                                   .description = "SEQUENCE",
                              17729                 :                :                                   .section = SECTION_PRE_DATA,
                              17730                 :                :                                   .createStmt = query->data,
                              17731                 :                :                                   .dropStmt = delqry->data));
                              17732                 :                : 
                              17733                 :                :     /*
                              17734                 :                :      * If the sequence is owned by a table column, emit the ALTER for it as a
                              17735                 :                :      * separate TOC entry immediately following the sequence's own entry. It's
                              17736                 :                :      * OK to do this rather than using full sorting logic, because the
                              17737                 :                :      * dependency that tells us it's owned will have forced the table to be
                              17738                 :                :      * created first.  We can't just include the ALTER in the TOC entry
                              17739                 :                :      * because it will fail if we haven't reassigned the sequence owner to
                              17740                 :                :      * match the table's owner.
                              17741                 :                :      *
                              17742                 :                :      * We need not schema-qualify the table reference because both sequence
                              17743                 :                :      * and table must be in the same schema.
                              17744                 :                :      */
 2565 peter_e@gmx.net         17745   [ +  +  +  + ]:            367 :     if (OidIsValid(tbinfo->owning_tab) && !tbinfo->is_identity_sequence)
                              17746                 :                :     {
  603 drowley@postgresql.o    17747                 :            145 :         owning_tab = findTableByOid(tbinfo->owning_tab);
                              17748                 :                : 
 2655 sfrost@snowman.net      17749         [ -  + ]:            145 :         if (owning_tab == NULL)
  737 tgl@sss.pgh.pa.us       17750                 :UBC           0 :             pg_fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found",
                              17751                 :                :                      tbinfo->owning_tab, tbinfo->dobj.catId.oid);
                              17752                 :                : 
 2655 sfrost@snowman.net      17753         [ +  + ]:CBC         145 :         if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17754                 :                :         {
 4188 tgl@sss.pgh.pa.us       17755                 :            143 :             resetPQExpBuffer(query);
                              17756                 :            143 :             appendPQExpBuffer(query, "ALTER SEQUENCE %s",
 2239                         17757                 :            143 :                               fmtQualifiedDumpable(tbinfo));
 4188                         17758                 :            143 :             appendPQExpBuffer(query, " OWNED BY %s",
 2239                         17759                 :            143 :                               fmtQualifiedDumpable(owning_tab));
 4188                         17760                 :            143 :             appendPQExpBuffer(query, ".%s;\n",
 2489                         17761                 :            143 :                               fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
                              17762                 :                : 
 2930 sfrost@snowman.net      17763         [ +  - ]:            143 :             if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17764                 :            143 :                 ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    17765                 :            143 :                              ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              17766                 :                :                                           .namespace = tbinfo->dobj.namespace->dobj.name,
                              17767                 :                :                                           .owner = tbinfo->rolname,
                              17768                 :                :                                           .description = "SEQUENCE OWNED BY",
                              17769                 :                :                                           .section = SECTION_PRE_DATA,
                              17770                 :                :                                           .createStmt = query->data,
                              17771                 :                :                                           .deps = &(tbinfo->dobj.dumpId),
                              17772                 :                :                                           .nDeps = 1));
                              17773                 :                :         }
                              17774                 :                :     }
                              17775                 :                : 
                              17776                 :                :     /* Dump Sequence Comments and Security Labels */
 2930 sfrost@snowman.net      17777         [ -  + ]:            367 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       17778                 :UBC           0 :         dumpComment(fout, "SEQUENCE", qseqname,
 2930 sfrost@snowman.net      17779                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              17780                 :              0 :                     tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              17781                 :                : 
 2930 sfrost@snowman.net      17782         [ -  + ]:CBC         367 :     if (tbinfo->dobj.dump & DUMP_COMPONENT_SECLABEL)
 2239 tgl@sss.pgh.pa.us       17783                 :UBC           0 :         dumpSecLabel(fout, "SEQUENCE", qseqname,
 2930 sfrost@snowman.net      17784                 :              0 :                      tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              17785                 :              0 :                      tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
                              17786                 :                : 
 8277 tgl@sss.pgh.pa.us       17787                 :CBC         367 :     PQclear(res);
                              17788                 :                : 
 8290                         17789                 :            367 :     destroyPQExpBuffer(query);
                              17790                 :            367 :     destroyPQExpBuffer(delqry);
 2239                         17791                 :            367 :     free(qseqname);
 9874 vadim4o@yahoo.com       17792                 :            367 : }
                              17793                 :                : 
                              17794                 :                : /*
                              17795                 :                :  * dumpSequenceData
                              17796                 :                :  *    write the data of one user-defined sequence
                              17797                 :                :  */
                              17798                 :                : static void
 1159 peter@eisentraut.org    17799                 :            385 : dumpSequenceData(Archive *fout, const TableDataInfo *tdinfo)
                              17800                 :                : {
 4188 tgl@sss.pgh.pa.us       17801                 :            385 :     TableInfo  *tbinfo = tdinfo->tdtable;
                              17802                 :                :     PGresult   *res;
                              17803                 :                :     char       *last;
                              17804                 :                :     bool        called;
                              17805                 :            385 :     PQExpBuffer query = createPQExpBuffer();
                              17806                 :                : 
                              17807                 :            385 :     appendPQExpBuffer(query,
                              17808                 :                :                       "SELECT last_value, is_called FROM %s",
 2239                         17809                 :            385 :                       fmtQualifiedDumpable(tbinfo));
                              17810                 :                : 
 4188                         17811                 :            385 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              17812                 :                : 
                              17813         [ -  + ]:            385 :     if (PQntuples(res) != 1)
  737 tgl@sss.pgh.pa.us       17814                 :UBC           0 :         pg_fatal(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)",
                              17815                 :                :                           "query to get data of sequence \"%s\" returned %d rows (expected 1)",
                              17816                 :                :                           PQntuples(res)),
                              17817                 :                :                  tbinfo->dobj.name, PQntuples(res));
                              17818                 :                : 
 4188 tgl@sss.pgh.pa.us       17819                 :CBC         385 :     last = PQgetvalue(res, 0, 0);
                              17820                 :            385 :     called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
                              17821                 :                : 
                              17822                 :            385 :     resetPQExpBuffer(query);
 3800 heikki.linnakangas@i    17823                 :            385 :     appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
 2239 tgl@sss.pgh.pa.us       17824                 :            385 :     appendStringLiteralAH(query, fmtQualifiedDumpable(tbinfo), fout);
 4188                         17825         [ +  + ]:            385 :     appendPQExpBuffer(query, ", %s, %s);\n",
                              17826                 :                :                       last, (called ? "true" : "false"));
                              17827                 :                : 
 2642 sfrost@snowman.net      17828         [ +  - ]:            385 :     if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA)
 2930                         17829                 :            385 :         ArchiveEntry(fout, nilCatalogId, createDumpId(),
 1899 alvherre@alvh.no-ip.    17830                 :            385 :                      ARCHIVE_OPTS(.tag = tbinfo->dobj.name,
                              17831                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              17832                 :                :                                   .owner = tbinfo->rolname,
                              17833                 :                :                                   .description = "SEQUENCE SET",
                              17834                 :                :                                   .section = SECTION_DATA,
                              17835                 :                :                                   .createStmt = query->data,
                              17836                 :                :                                   .deps = &(tbinfo->dobj.dumpId),
                              17837                 :                :                                   .nDeps = 1));
                              17838                 :                : 
 4188 tgl@sss.pgh.pa.us       17839                 :            385 :     PQclear(res);
                              17840                 :                : 
                              17841                 :            385 :     destroyPQExpBuffer(query);
                              17842                 :            385 : }
                              17843                 :                : 
                              17844                 :                : /*
                              17845                 :                :  * dumpTrigger
                              17846                 :                :  *    write the declaration of one user-defined table trigger
                              17847                 :                :  */
                              17848                 :                : static void
 1159 peter@eisentraut.org    17849                 :            508 : dumpTrigger(Archive *fout, const TriggerInfo *tginfo)
                              17850                 :                : {
 3014 tgl@sss.pgh.pa.us       17851                 :            508 :     DumpOptions *dopt = fout->dopt;
 7435                         17852                 :            508 :     TableInfo  *tbinfo = tginfo->tgtable;
                              17853                 :                :     PQExpBuffer query;
                              17854                 :                :     PQExpBuffer delqry;
                              17855                 :                :     PQExpBuffer trigprefix;
                              17856                 :                :     PQExpBuffer trigidentity;
                              17857                 :                :     char       *qtabname;
                              17858                 :                :     char       *tag;
                              17859                 :                : 
                              17860                 :                :     /* Do nothing in data-only dump */
 3470 alvherre@alvh.no-ip.    17861         [ +  + ]:            508 :     if (dopt->dataOnly)
 7912 tgl@sss.pgh.pa.us       17862                 :             16 :         return;
                              17863                 :                : 
 7435                         17864                 :            492 :     query = createPQExpBuffer();
                              17865                 :            492 :     delqry = createPQExpBuffer();
 2239                         17866                 :            492 :     trigprefix = createPQExpBuffer();
 1495 alvherre@alvh.no-ip.    17867                 :            492 :     trigidentity = createPQExpBuffer();
                              17868                 :                : 
 2239 tgl@sss.pgh.pa.us       17869                 :            492 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              17870                 :                : 
 1495 alvherre@alvh.no-ip.    17871                 :            492 :     appendPQExpBuffer(trigidentity, "%s ", fmtId(tginfo->dobj.name));
                              17872                 :            492 :     appendPQExpBuffer(trigidentity, "ON %s", fmtQualifiedDumpable(tbinfo));
                              17873                 :                : 
   91 peter@eisentraut.org    17874                 :GNC         492 :     appendPQExpBuffer(query, "%s;\n", tginfo->tgdef);
 1495 alvherre@alvh.no-ip.    17875                 :CBC         492 :     appendPQExpBuffer(delqry, "DROP TRIGGER %s;\n", trigidentity->data);
                              17876                 :                : 
                              17877                 :                :     /* Triggers can depend on extensions */
                              17878                 :            492 :     append_depends_on_extension(fout, query, &tginfo->dobj,
                              17879                 :                :                                 "pg_catalog.pg_trigger", "TRIGGER",
                              17880                 :            492 :                                 trigidentity->data);
                              17881                 :                : 
  830                         17882         [ +  + ]:            492 :     if (tginfo->tgispartition)
                              17883                 :                :     {
                              17884         [ -  + ]:            121 :         Assert(tbinfo->ispartition);
                              17885                 :                : 
                              17886                 :                :         /*
                              17887                 :                :          * Partition triggers only appear here because their 'tgenabled' flag
                              17888                 :                :          * differs from its parent's.  The trigger is created already, so
                              17889                 :                :          * remove the CREATE and replace it with an ALTER.  (Clear out the
                              17890                 :                :          * DROP query too, so that pg_dump --create does not cause errors.)
                              17891                 :                :          */
 1003                         17892                 :            121 :         resetPQExpBuffer(query);
                              17893                 :            121 :         resetPQExpBuffer(delqry);
 1003 alvherre@alvh.no-ip.    17894                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
 1003 alvherre@alvh.no-ip.    17895         [ -  + ]:CBC         121 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
                              17896                 :            121 :                           fmtQualifiedDumpable(tbinfo));
                              17897   [ +  -  +  +  :            121 :         switch (tginfo->tgenabled)
                                                 - ]
                              17898                 :                :         {
                              17899                 :             42 :             case 'f':
                              17900                 :                :             case 'D':
                              17901                 :             42 :                 appendPQExpBufferStr(query, "DISABLE");
                              17902                 :             42 :                 break;
 1003 alvherre@alvh.no-ip.    17903                 :UBC           0 :             case 't':
                              17904                 :                :             case 'O':
                              17905                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
                              17906                 :              0 :                 break;
 1003 alvherre@alvh.no-ip.    17907                 :CBC          37 :             case 'R':
                              17908                 :             37 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
                              17909                 :             37 :                 break;
                              17910                 :             42 :             case 'A':
                              17911                 :             42 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
                              17912                 :             42 :                 break;
                              17913                 :                :         }
                              17914                 :            121 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
                              17915                 :            121 :                           fmtId(tginfo->dobj.name));
                              17916                 :                :     }
                              17917   [ +  -  -  + ]:            371 :     else if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
                              17918                 :                :     {
 1486 alvherre@alvh.no-ip.    17919                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER %sTABLE %s ",
                              17920         [ #  # ]:              0 :                           tbinfo->relkind == RELKIND_FOREIGN_TABLE ? "FOREIGN " : "",
 2239 tgl@sss.pgh.pa.us       17921                 :              0 :                           fmtQualifiedDumpable(tbinfo));
 6236 JanWieck@Yahoo.com      17922   [ #  #  #  # ]:              0 :         switch (tginfo->tgenabled)
                              17923                 :                :         {
                              17924                 :              0 :             case 'D':
                              17925                 :                :             case 'f':
 3800 heikki.linnakangas@i    17926                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 6236 JanWieck@Yahoo.com      17927                 :              0 :                 break;
                              17928                 :              0 :             case 'A':
 3800 heikki.linnakangas@i    17929                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 6236 JanWieck@Yahoo.com      17930                 :              0 :                 break;
                              17931                 :              0 :             case 'R':
 3800 heikki.linnakangas@i    17932                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 6236 JanWieck@Yahoo.com      17933                 :              0 :                 break;
                              17934                 :              0 :             default:
 3800 heikki.linnakangas@i    17935                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 6236 JanWieck@Yahoo.com      17936                 :              0 :                 break;
                              17937                 :                :         }
                              17938                 :              0 :         appendPQExpBuffer(query, " TRIGGER %s;\n",
 6809 tgl@sss.pgh.pa.us       17939                 :              0 :                           fmtId(tginfo->dobj.name));
                              17940                 :                :     }
                              17941                 :                : 
 2239 tgl@sss.pgh.pa.us       17942                 :CBC         492 :     appendPQExpBuffer(trigprefix, "TRIGGER %s ON",
 4813                         17943                 :            492 :                       fmtId(tginfo->dobj.name));
                              17944                 :                : 
 2971 peter_e@gmx.net         17945                 :            492 :     tag = psprintf("%s %s", tbinfo->dobj.name, tginfo->dobj.name);
                              17946                 :                : 
 2930 sfrost@snowman.net      17947         [ +  - ]:            492 :     if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              17948                 :            492 :         ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    17949                 :            492 :                      ARCHIVE_OPTS(.tag = tag,
                              17950                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              17951                 :                :                                   .owner = tbinfo->rolname,
                              17952                 :                :                                   .description = "TRIGGER",
                              17953                 :                :                                   .section = SECTION_POST_DATA,
                              17954                 :                :                                   .createStmt = query->data,
                              17955                 :                :                                   .dropStmt = delqry->data));
                              17956                 :                : 
 2930 sfrost@snowman.net      17957         [ -  + ]:            492 :     if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       17958                 :UBC           0 :         dumpComment(fout, trigprefix->data, qtabname,
 2930 sfrost@snowman.net      17959                 :              0 :                     tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
                              17960                 :              0 :                     tginfo->dobj.catId, 0, tginfo->dobj.dumpId);
                              17961                 :                : 
 2971 peter_e@gmx.net         17962                 :CBC         492 :     free(tag);
 7435 tgl@sss.pgh.pa.us       17963                 :            492 :     destroyPQExpBuffer(query);
                              17964                 :            492 :     destroyPQExpBuffer(delqry);
 2239                         17965                 :            492 :     destroyPQExpBuffer(trigprefix);
 1495 alvherre@alvh.no-ip.    17966                 :            492 :     destroyPQExpBuffer(trigidentity);
 2239 tgl@sss.pgh.pa.us       17967                 :            492 :     free(qtabname);
                              17968                 :                : }
                              17969                 :                : 
                              17970                 :                : /*
                              17971                 :                :  * dumpEventTrigger
                              17972                 :                :  *    write the declaration of one user-defined event trigger
                              17973                 :                :  */
                              17974                 :                : static void
 1159 peter@eisentraut.org    17975                 :             43 : dumpEventTrigger(Archive *fout, const EventTriggerInfo *evtinfo)
                              17976                 :                : {
 3014 tgl@sss.pgh.pa.us       17977                 :             43 :     DumpOptions *dopt = fout->dopt;
                              17978                 :                :     PQExpBuffer query;
                              17979                 :                :     PQExpBuffer delqry;
                              17980                 :                :     char       *qevtname;
                              17981                 :                : 
                              17982                 :                :     /* Do nothing in data-only dump */
  860                         17983         [ +  + ]:             43 :     if (dopt->dataOnly)
 3758                         17984                 :              3 :         return;
                              17985                 :                : 
 4288 rhaas@postgresql.org    17986                 :             40 :     query = createPQExpBuffer();
 2458 tgl@sss.pgh.pa.us       17987                 :             40 :     delqry = createPQExpBuffer();
                              17988                 :                : 
 2239                         17989                 :             40 :     qevtname = pg_strdup(fmtId(evtinfo->dobj.name));
                              17990                 :                : 
 3800 heikki.linnakangas@i    17991                 :             40 :     appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
 2239 tgl@sss.pgh.pa.us       17992                 :             40 :     appendPQExpBufferStr(query, qevtname);
 3800 heikki.linnakangas@i    17993                 :             40 :     appendPQExpBufferStr(query, " ON ");
 4288 rhaas@postgresql.org    17994                 :             40 :     appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
                              17995                 :                : 
                              17996         [ +  + ]:             40 :     if (strcmp("", evtinfo->evttags) != 0)
                              17997                 :                :     {
 4288 rhaas@postgresql.org    17998                 :GBC           5 :         appendPQExpBufferStr(query, "\n         WHEN TAG IN (");
                              17999                 :              5 :         appendPQExpBufferStr(query, evtinfo->evttags);
 3209 heikki.linnakangas@i    18000                 :              5 :         appendPQExpBufferChar(query, ')');
                              18001                 :                :     }
                              18002                 :                : 
 1893 peter@eisentraut.org    18003                 :CBC          40 :     appendPQExpBufferStr(query, "\n   EXECUTE FUNCTION ");
 4288 rhaas@postgresql.org    18004                 :             40 :     appendPQExpBufferStr(query, evtinfo->evtfname);
 3800 heikki.linnakangas@i    18005                 :             40 :     appendPQExpBufferStr(query, "();\n");
                              18006                 :                : 
 4288 rhaas@postgresql.org    18007         [ -  + ]:             40 :     if (evtinfo->evtenabled != 'O')
                              18008                 :                :     {
 4288 rhaas@postgresql.org    18009                 :UBC           0 :         appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
                              18010                 :                :                           qevtname);
                              18011   [ #  #  #  # ]:              0 :         switch (evtinfo->evtenabled)
                              18012                 :                :         {
                              18013                 :              0 :             case 'D':
 3800 heikki.linnakangas@i    18014                 :              0 :                 appendPQExpBufferStr(query, "DISABLE");
 4288 rhaas@postgresql.org    18015                 :              0 :                 break;
                              18016                 :              0 :             case 'A':
 3800 heikki.linnakangas@i    18017                 :              0 :                 appendPQExpBufferStr(query, "ENABLE ALWAYS");
 4288 rhaas@postgresql.org    18018                 :              0 :                 break;
                              18019                 :              0 :             case 'R':
 3800 heikki.linnakangas@i    18020                 :              0 :                 appendPQExpBufferStr(query, "ENABLE REPLICA");
 4288 rhaas@postgresql.org    18021                 :              0 :                 break;
                              18022                 :              0 :             default:
 3800 heikki.linnakangas@i    18023                 :              0 :                 appendPQExpBufferStr(query, "ENABLE");
 4288 rhaas@postgresql.org    18024                 :              0 :                 break;
                              18025                 :                :         }
 3800 heikki.linnakangas@i    18026                 :              0 :         appendPQExpBufferStr(query, ";\n");
                              18027                 :                :     }
                              18028                 :                : 
 2458 tgl@sss.pgh.pa.us       18029                 :CBC          40 :     appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n",
                              18030                 :                :                       qevtname);
                              18031                 :                : 
 2077                         18032         [ +  + ]:             40 :     if (dopt->binary_upgrade)
                              18033                 :              2 :         binary_upgrade_extension_member(query, &evtinfo->dobj,
                              18034                 :                :                                         "EVENT TRIGGER", qevtname, NULL);
                              18035                 :                : 
 2930 sfrost@snowman.net      18036         [ +  - ]:             40 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18037                 :             40 :         ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    18038                 :             40 :                      ARCHIVE_OPTS(.tag = evtinfo->dobj.name,
                              18039                 :                :                                   .owner = evtinfo->evtowner,
                              18040                 :                :                                   .description = "EVENT TRIGGER",
                              18041                 :                :                                   .section = SECTION_POST_DATA,
                              18042                 :                :                                   .createStmt = query->data,
                              18043                 :                :                                   .dropStmt = delqry->data));
                              18044                 :                : 
 2930 sfrost@snowman.net      18045         [ -  + ]:             40 :     if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       18046                 :UBC           0 :         dumpComment(fout, "EVENT TRIGGER", qevtname,
 2930 sfrost@snowman.net      18047                 :              0 :                     NULL, evtinfo->evtowner,
                              18048                 :              0 :                     evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
                              18049                 :                : 
 4288 rhaas@postgresql.org    18050                 :CBC          40 :     destroyPQExpBuffer(query);
 2458 tgl@sss.pgh.pa.us       18051                 :             40 :     destroyPQExpBuffer(delqry);
 2239                         18052                 :             40 :     free(qevtname);
                              18053                 :                : }
                              18054                 :                : 
                              18055                 :                : /*
                              18056                 :                :  * dumpRule
                              18057                 :                :  *      Dump a rule
                              18058                 :                :  */
                              18059                 :                : static void
 1159 peter@eisentraut.org    18060                 :            940 : dumpRule(Archive *fout, const RuleInfo *rinfo)
                              18061                 :                : {
 3014 tgl@sss.pgh.pa.us       18062                 :            940 :     DumpOptions *dopt = fout->dopt;
 7435                         18063                 :            940 :     TableInfo  *tbinfo = rinfo->ruletable;
                              18064                 :                :     bool        is_view;
                              18065                 :                :     PQExpBuffer query;
                              18066                 :                :     PQExpBuffer cmd;
                              18067                 :                :     PQExpBuffer delcmd;
                              18068                 :                :     PQExpBuffer ruleprefix;
                              18069                 :                :     char       *qtabname;
                              18070                 :                :     PGresult   *res;
                              18071                 :                :     char       *tag;
                              18072                 :                : 
                              18073                 :                :     /* Do nothing in data-only dump */
  860                         18074         [ +  + ]:            940 :     if (dopt->dataOnly)
 7435                         18075                 :             30 :         return;
                              18076                 :                : 
                              18077                 :                :     /*
                              18078                 :                :      * If it is an ON SELECT rule that is created implicitly by CREATE VIEW,
                              18079                 :                :      * we do not want to dump it as a separate object.
                              18080                 :                :      */
 7061                         18081         [ +  + ]:            910 :     if (!rinfo->separate)
 7435                         18082                 :            703 :         return;
                              18083                 :                : 
                              18084                 :                :     /*
                              18085                 :                :      * If it's an ON SELECT rule, we want to print it as a view definition,
                              18086                 :                :      * instead of a rule.
                              18087                 :                :      */
 2705                         18088   [ +  +  +  - ]:            207 :     is_view = (rinfo->ev_type == '1' && rinfo->is_instead);
                              18089                 :                : 
 7435                         18090                 :            207 :     query = createPQExpBuffer();
                              18091                 :            207 :     cmd = createPQExpBuffer();
                              18092                 :            207 :     delcmd = createPQExpBuffer();
 2239                         18093                 :            207 :     ruleprefix = createPQExpBuffer();
                              18094                 :                : 
                              18095                 :            207 :     qtabname = pg_strdup(fmtId(tbinfo->dobj.name));
                              18096                 :                : 
 2705                         18097         [ +  + ]:            207 :     if (is_view)
                              18098                 :                :     {
                              18099                 :                :         PQExpBuffer result;
                              18100                 :                : 
                              18101                 :                :         /*
                              18102                 :                :          * We need OR REPLACE here because we'll be replacing a dummy view.
                              18103                 :                :          * Otherwise this should look largely like the regular view dump code.
                              18104                 :                :          */
                              18105                 :             10 :         appendPQExpBuffer(cmd, "CREATE OR REPLACE VIEW %s",
 2239                         18106                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 2705                         18107         [ -  + ]:             10 :         if (nonemptyReloptions(tbinfo->reloptions))
                              18108                 :                :         {
 2705 tgl@sss.pgh.pa.us       18109                 :UBC           0 :             appendPQExpBufferStr(cmd, " WITH (");
                              18110                 :              0 :             appendReloptionsArrayAH(cmd, tbinfo->reloptions, "", fout);
                              18111                 :              0 :             appendPQExpBufferChar(cmd, ')');
                              18112                 :                :         }
 2705 tgl@sss.pgh.pa.us       18113                 :CBC          10 :         result = createViewAsClause(fout, tbinfo);
                              18114                 :             10 :         appendPQExpBuffer(cmd, " AS\n%s", result->data);
                              18115                 :             10 :         destroyPQExpBuffer(result);
                              18116         [ -  + ]:             10 :         if (tbinfo->checkoption != NULL)
 2705 tgl@sss.pgh.pa.us       18117                 :UBC           0 :             appendPQExpBuffer(cmd, "\n  WITH %s CHECK OPTION",
                              18118                 :                :                               tbinfo->checkoption);
 2705 tgl@sss.pgh.pa.us       18119                 :CBC          10 :         appendPQExpBufferStr(cmd, ";\n");
                              18120                 :                :     }
                              18121                 :                :     else
                              18122                 :                :     {
                              18123                 :                :         /* In the rule case, just print pg_get_ruledef's result verbatim */
                              18124                 :            197 :         appendPQExpBuffer(query,
                              18125                 :                :                           "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid)",
                              18126                 :            197 :                           rinfo->dobj.catId.oid);
                              18127                 :                : 
                              18128                 :            197 :         res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              18129                 :                : 
                              18130         [ -  + ]:            197 :         if (PQntuples(res) != 1)
  737 tgl@sss.pgh.pa.us       18131                 :UBC           0 :             pg_fatal("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned",
                              18132                 :                :                      rinfo->dobj.name, tbinfo->dobj.name);
                              18133                 :                : 
 2705 tgl@sss.pgh.pa.us       18134                 :CBC         197 :         printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
                              18135                 :                : 
                              18136                 :            197 :         PQclear(res);
                              18137                 :                :     }
                              18138                 :                : 
                              18139                 :                :     /*
                              18140                 :                :      * Add the command to alter the rules replication firing semantics if it
                              18141                 :                :      * differs from the default.
                              18142                 :                :      */
 6236 JanWieck@Yahoo.com      18143         [ +  + ]:            207 :     if (rinfo->ev_enabled != 'O')
                              18144                 :                :     {
 2239 tgl@sss.pgh.pa.us       18145                 :GBC          15 :         appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtQualifiedDumpable(tbinfo));
 6236 JanWieck@Yahoo.com      18146   [ -  -  +  - ]:             15 :         switch (rinfo->ev_enabled)
                              18147                 :                :         {
 6236 JanWieck@Yahoo.com      18148                 :UBC           0 :             case 'A':
                              18149                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE ALWAYS RULE %s;\n",
 5995 bruce@momjian.us        18150                 :              0 :                                   fmtId(rinfo->dobj.name));
 6236 JanWieck@Yahoo.com      18151                 :              0 :                 break;
                              18152                 :              0 :             case 'R':
                              18153                 :              0 :                 appendPQExpBuffer(cmd, "ENABLE REPLICA RULE %s;\n",
 5995 bruce@momjian.us        18154                 :              0 :                                   fmtId(rinfo->dobj.name));
 6236 JanWieck@Yahoo.com      18155                 :              0 :                 break;
 6236 JanWieck@Yahoo.com      18156                 :GBC          15 :             case 'D':
                              18157                 :             15 :                 appendPQExpBuffer(cmd, "DISABLE RULE %s;\n",
 5995 bruce@momjian.us        18158                 :             15 :                                   fmtId(rinfo->dobj.name));
 6236 JanWieck@Yahoo.com      18159                 :             15 :                 break;
                              18160                 :                :         }
                              18161                 :                :     }
                              18162                 :                : 
 2705 tgl@sss.pgh.pa.us       18163         [ +  + ]:CBC         207 :     if (is_view)
                              18164                 :                :     {
                              18165                 :                :         /*
                              18166                 :                :          * We can't DROP a view's ON SELECT rule.  Instead, use CREATE OR
                              18167                 :                :          * REPLACE VIEW to replace the rule with something with minimal
                              18168                 :                :          * dependencies.
                              18169                 :                :          */
                              18170                 :                :         PQExpBuffer result;
                              18171                 :                : 
 2239                         18172                 :             10 :         appendPQExpBuffer(delcmd, "CREATE OR REPLACE VIEW %s",
                              18173                 :             10 :                           fmtQualifiedDumpable(tbinfo));
 2705                         18174                 :             10 :         result = createDummyViewAsClause(fout, tbinfo);
                              18175                 :             10 :         appendPQExpBuffer(delcmd, " AS\n%s;\n", result->data);
                              18176                 :             10 :         destroyPQExpBuffer(result);
                              18177                 :                :     }
                              18178                 :                :     else
                              18179                 :                :     {
                              18180                 :            197 :         appendPQExpBuffer(delcmd, "DROP RULE %s ",
                              18181                 :            197 :                           fmtId(rinfo->dobj.name));
 2239                         18182                 :            197 :         appendPQExpBuffer(delcmd, "ON %s;\n",
                              18183                 :            197 :                           fmtQualifiedDumpable(tbinfo));
                              18184                 :                :     }
                              18185                 :                : 
                              18186                 :            207 :     appendPQExpBuffer(ruleprefix, "RULE %s ON",
 4813                         18187                 :            207 :                       fmtId(rinfo->dobj.name));
                              18188                 :                : 
 2971 peter_e@gmx.net         18189                 :            207 :     tag = psprintf("%s %s", tbinfo->dobj.name, rinfo->dobj.name);
                              18190                 :                : 
 2930 sfrost@snowman.net      18191         [ +  - ]:            207 :     if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
                              18192                 :            207 :         ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId,
 1899 alvherre@alvh.no-ip.    18193                 :            207 :                      ARCHIVE_OPTS(.tag = tag,
                              18194                 :                :                                   .namespace = tbinfo->dobj.namespace->dobj.name,
                              18195                 :                :                                   .owner = tbinfo->rolname,
                              18196                 :                :                                   .description = "RULE",
                              18197                 :                :                                   .section = SECTION_POST_DATA,
                              18198                 :                :                                   .createStmt = cmd->data,
                              18199                 :                :                                   .dropStmt = delcmd->data));
                              18200                 :                : 
                              18201                 :                :     /* Dump rule comments */
 2930 sfrost@snowman.net      18202         [ -  + ]:            207 :     if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT)
 2239 tgl@sss.pgh.pa.us       18203                 :UBC           0 :         dumpComment(fout, ruleprefix->data, qtabname,
 2930 sfrost@snowman.net      18204                 :              0 :                     tbinfo->dobj.namespace->dobj.name,
                              18205                 :                :                     tbinfo->rolname,
                              18206                 :              0 :                     rinfo->dobj.catId, 0, rinfo->dobj.dumpId);
                              18207                 :                : 
 2971 peter_e@gmx.net         18208                 :CBC         207 :     free(tag);
 8010 tgl@sss.pgh.pa.us       18209                 :            207 :     destroyPQExpBuffer(query);
 7435                         18210                 :            207 :     destroyPQExpBuffer(cmd);
                              18211                 :            207 :     destroyPQExpBuffer(delcmd);
 2239                         18212                 :            207 :     destroyPQExpBuffer(ruleprefix);
                              18213                 :            207 :     free(qtabname);
                              18214                 :                : }
                              18215                 :                : 
                              18216                 :                : /*
                              18217                 :                :  * getExtensionMembership --- obtain extension membership data
                              18218                 :                :  *
                              18219                 :                :  * We need to identify objects that are extension members as soon as they're
                              18220                 :                :  * loaded, so that we can correctly determine whether they need to be dumped.
                              18221                 :                :  * Generally speaking, extension member objects will get marked as *not* to
                              18222                 :                :  * be dumped, as they will be recreated by the single CREATE EXTENSION
                              18223                 :                :  * command.  However, in binary upgrade mode we still need to dump the members
                              18224                 :                :  * individually.
                              18225                 :                :  */
                              18226                 :                : void
 3014                         18227                 :            156 : getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                              18228                 :                :                        int numExtensions)
                              18229                 :                : {
                              18230                 :                :     PQExpBuffer query;
                              18231                 :                :     PGresult   *res;
                              18232                 :                :     int         ntups,
                              18233                 :                :                 i;
                              18234                 :                :     int         i_classid,
                              18235                 :                :                 i_objid,
                              18236                 :                :                 i_refobjid;
                              18237                 :                :     ExtensionInfo *ext;
                              18238                 :                : 
                              18239                 :                :     /* Nothing to do if no extensions */
 4813                         18240         [ -  + ]:            156 :     if (numExtensions == 0)
 4813 tgl@sss.pgh.pa.us       18241                 :UBC           0 :         return;
                              18242                 :                : 
 4813 tgl@sss.pgh.pa.us       18243                 :CBC         156 :     query = createPQExpBuffer();
                              18244                 :                : 
                              18245                 :                :     /* refclassid constraint is redundant but may speed the search */
 3800 heikki.linnakangas@i    18246                 :            156 :     appendPQExpBufferStr(query, "SELECT "
                              18247                 :                :                          "classid, objid, refobjid "
                              18248                 :                :                          "FROM pg_depend "
                              18249                 :                :                          "WHERE refclassid = 'pg_extension'::regclass "
                              18250                 :                :                          "AND deptype = 'e' "
                              18251                 :                :                          "ORDER BY 3");
                              18252                 :                : 
 4450 rhaas@postgresql.org    18253                 :            156 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              18254                 :                : 
 4813 tgl@sss.pgh.pa.us       18255                 :            156 :     ntups = PQntuples(res);
                              18256                 :                : 
                              18257                 :            156 :     i_classid = PQfnumber(res, "classid");
                              18258                 :            156 :     i_objid = PQfnumber(res, "objid");
                              18259                 :            156 :     i_refobjid = PQfnumber(res, "refobjid");
                              18260                 :                : 
                              18261                 :                :     /*
                              18262                 :                :      * Since we ordered the SELECT by referenced ID, we can expect that
                              18263                 :                :      * multiple entries for the same extension will appear together; this
                              18264                 :                :      * saves on searches.
                              18265                 :                :      */
 3014                         18266                 :            156 :     ext = NULL;
                              18267                 :                : 
 4813                         18268         [ +  + ]:           1380 :     for (i = 0; i < ntups; i++)
                              18269                 :                :     {
                              18270                 :                :         CatalogId   objId;
                              18271                 :                :         Oid         extId;
                              18272                 :                : 
                              18273                 :           1224 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              18274                 :           1224 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
 3014                         18275                 :           1224 :         extId = atooid(PQgetvalue(res, i, i_refobjid));
                              18276                 :                : 
                              18277         [ +  + ]:           1224 :         if (ext == NULL ||
                              18278         [ +  + ]:           1068 :             ext->dobj.catId.oid != extId)
                              18279                 :            181 :             ext = findExtensionByOid(extId);
                              18280                 :                : 
                              18281         [ -  + ]:           1224 :         if (ext == NULL)
                              18282                 :                :         {
                              18283                 :                :             /* shouldn't happen */
 1840 peter@eisentraut.org    18284                 :UBC           0 :             pg_log_warning("could not find referenced extension %u", extId);
 4813 tgl@sss.pgh.pa.us       18285                 :              0 :             continue;
                              18286                 :                :         }
                              18287                 :                : 
  905 tgl@sss.pgh.pa.us       18288                 :CBC        1224 :         recordExtensionMembership(objId, ext);
                              18289                 :                :     }
                              18290                 :                : 
 3014                         18291                 :            156 :     PQclear(res);
                              18292                 :                : 
                              18293                 :            156 :     destroyPQExpBuffer(query);
                              18294                 :                : }
                              18295                 :                : 
                              18296                 :                : /*
                              18297                 :                :  * processExtensionTables --- deal with extension configuration tables
                              18298                 :                :  *
                              18299                 :                :  * There are two parts to this process:
                              18300                 :                :  *
                              18301                 :                :  * 1. Identify and create dump records for extension configuration tables.
                              18302                 :                :  *
                              18303                 :                :  *    Extensions can mark tables as "configuration", which means that the user
                              18304                 :                :  *    is able and expected to modify those tables after the extension has been
                              18305                 :                :  *    loaded.  For these tables, we dump out only the data- the structure is
                              18306                 :                :  *    expected to be handled at CREATE EXTENSION time, including any indexes or
                              18307                 :                :  *    foreign keys, which brings us to-
                              18308                 :                :  *
                              18309                 :                :  * 2. Record FK dependencies between configuration tables.
                              18310                 :                :  *
                              18311                 :                :  *    Due to the FKs being created at CREATE EXTENSION time and therefore before
                              18312                 :                :  *    the data is loaded, we have to work out what the best order for reloading
                              18313                 :                :  *    the data is, to avoid FK violations when the tables are restored.  This is
                              18314                 :                :  *    not perfect- we can't handle circular dependencies and if any exist they
                              18315                 :                :  *    will cause an invalid dump to be produced (though at least all of the data
                              18316                 :                :  *    is included for a user to manually restore).  This is currently documented
                              18317                 :                :  *    but perhaps we can provide a better solution in the future.
                              18318                 :                :  */
                              18319                 :                : void
                              18320                 :            155 : processExtensionTables(Archive *fout, ExtensionInfo extinfo[],
                              18321                 :                :                        int numExtensions)
                              18322                 :                : {
                              18323                 :            155 :     DumpOptions *dopt = fout->dopt;
                              18324                 :                :     PQExpBuffer query;
                              18325                 :                :     PGresult   *res;
                              18326                 :                :     int         ntups,
                              18327                 :                :                 i;
                              18328                 :                :     int         i_conrelid,
                              18329                 :                :                 i_confrelid;
                              18330                 :                : 
                              18331                 :                :     /* Nothing to do if no extensions */
                              18332         [ -  + ]:            155 :     if (numExtensions == 0)
 3014 tgl@sss.pgh.pa.us       18333                 :UBC           0 :         return;
                              18334                 :                : 
                              18335                 :                :     /*
                              18336                 :                :      * Identify extension configuration tables and create TableDataInfo
                              18337                 :                :      * objects for them, ensuring their data will be dumped even though the
                              18338                 :                :      * tables themselves won't be.
                              18339                 :                :      *
                              18340                 :                :      * Note that we create TableDataInfo objects even in schemaOnly mode, ie,
                              18341                 :                :      * user data in a configuration table is treated like schema data. This
                              18342                 :                :      * seems appropriate since system data in a config table would get
                              18343                 :                :      * reloaded by CREATE EXTENSION.  If the extension is not listed in the
                              18344                 :                :      * list of extensions to be included, none of its data is dumped.
                              18345                 :                :      */
 4813 tgl@sss.pgh.pa.us       18346         [ +  + ]:CBC         335 :     for (i = 0; i < numExtensions; i++)
                              18347                 :                :     {
 4447                         18348                 :            180 :         ExtensionInfo *curext = &(extinfo[i]);
                              18349                 :            180 :         char       *extconfig = curext->extconfig;
                              18350                 :            180 :         char       *extcondition = curext->extcondition;
 4753 bruce@momjian.us        18351                 :            180 :         char      **extconfigarray = NULL;
                              18352                 :            180 :         char      **extconditionarray = NULL;
 1242 michael@paquier.xyz     18353                 :            180 :         int         nconfigitems = 0;
                              18354                 :            180 :         int         nconditionitems = 0;
                              18355                 :                : 
                              18356                 :                :         /*
                              18357                 :                :          * Check if this extension is listed as to include in the dump.  If
                              18358                 :                :          * not, any table data associated with it is discarded.
                              18359                 :                :          */
 1095                         18360         [ +  + ]:            180 :         if (extension_include_oids.head != NULL &&
                              18361         [ +  + ]:              8 :             !simple_oid_list_member(&extension_include_oids,
                              18362                 :                :                                     curext->dobj.catId.oid))
                              18363                 :              6 :             continue;
                              18364                 :                : 
                              18365                 :                :         /*
                              18366                 :                :          * Check if this extension is listed as to exclude in the dump.  If
                              18367                 :                :          * yes, any table data associated with it is discarded.
                              18368                 :                :          */
   25 dean.a.rasheed@gmail    18369   [ +  +  +  + ]:GNC         180 :         if (extension_exclude_oids.head != NULL &&
                              18370                 :              4 :             simple_oid_list_member(&extension_exclude_oids,
                              18371                 :                :                                    curext->dobj.catId.oid))
                              18372                 :              2 :             continue;
                              18373                 :                : 
 1242 michael@paquier.xyz     18374   [ +  +  -  + ]:CBC         174 :         if (strlen(extconfig) != 0 || strlen(extcondition) != 0)
                              18375                 :                :         {
                              18376                 :                :             int         j;
                              18377                 :                : 
                              18378         [ -  + ]:             20 :             if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems))
  737 tgl@sss.pgh.pa.us       18379                 :UBC           0 :                 pg_fatal("could not parse %s array", "extconfig");
 1242 michael@paquier.xyz     18380         [ -  + ]:CBC          20 :             if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems))
  737 tgl@sss.pgh.pa.us       18381                 :UBC           0 :                 pg_fatal("could not parse %s array", "extcondition");
 1242 michael@paquier.xyz     18382         [ -  + ]:CBC          20 :             if (nconfigitems != nconditionitems)
  737 tgl@sss.pgh.pa.us       18383                 :UBC           0 :                 pg_fatal("mismatched number of configurations and conditions for extension");
                              18384                 :                : 
 4813 tgl@sss.pgh.pa.us       18385         [ +  + ]:CBC          60 :             for (j = 0; j < nconfigitems; j++)
                              18386                 :                :             {
                              18387                 :                :                 TableInfo  *configtbl;
 4006 mail@joeconway.com      18388                 :             40 :                 Oid         configtbloid = atooid(extconfigarray[j]);
 2930 sfrost@snowman.net      18389                 :             40 :                 bool        dumpobj =
  331 tgl@sss.pgh.pa.us       18390                 :             40 :                     curext->dobj.dump & DUMP_COMPONENT_DEFINITION;
                              18391                 :                : 
 4006 mail@joeconway.com      18392                 :             40 :                 configtbl = findTableByOid(configtbloid);
 4449 tgl@sss.pgh.pa.us       18393         [ -  + ]:             40 :                 if (configtbl == NULL)
 4449 tgl@sss.pgh.pa.us       18394                 :UBC           0 :                     continue;
                              18395                 :                : 
                              18396                 :                :                 /*
                              18397                 :                :                  * Tables of not-to-be-dumped extensions shouldn't be dumped
                              18398                 :                :                  * unless the table or its schema is explicitly included
                              18399                 :                :                  */
 2930 sfrost@snowman.net      18400         [ +  + ]:CBC          40 :                 if (!(curext->dobj.dump & DUMP_COMPONENT_DEFINITION))
                              18401                 :                :                 {
                              18402                 :                :                     /* check table explicitly requested */
 4006 mail@joeconway.com      18403   [ -  +  -  - ]:              2 :                     if (table_include_oids.head != NULL &&
 4006 mail@joeconway.com      18404                 :UBC           0 :                         simple_oid_list_member(&table_include_oids,
                              18405                 :                :                                                configtbloid))
                              18406                 :              0 :                         dumpobj = true;
                              18407                 :                : 
                              18408                 :                :                     /* check table's schema explicitly requested */
 2930 sfrost@snowman.net      18409         [ +  - ]:CBC           2 :                     if (configtbl->dobj.namespace->dobj.dump &
                              18410                 :                :                         DUMP_COMPONENT_DATA)
 4006 mail@joeconway.com      18411                 :              2 :                         dumpobj = true;
                              18412                 :                :                 }
                              18413                 :                : 
                              18414                 :                :                 /* check table excluded by an exclusion switch */
                              18415   [ +  +  +  + ]:             44 :                 if (table_exclude_oids.head != NULL &&
                              18416                 :              4 :                     simple_oid_list_member(&table_exclude_oids,
                              18417                 :                :                                            configtbloid))
                              18418                 :              1 :                     dumpobj = false;
                              18419                 :                : 
                              18420                 :                :                 /* check schema excluded by an exclusion switch */
                              18421         [ -  + ]:             40 :                 if (simple_oid_list_member(&schema_exclude_oids,
 2489 tgl@sss.pgh.pa.us       18422                 :             40 :                                            configtbl->dobj.namespace->dobj.catId.oid))
 4006 mail@joeconway.com      18423                 :UBC           0 :                     dumpobj = false;
                              18424                 :                : 
 4006 mail@joeconway.com      18425         [ +  + ]:CBC          40 :                 if (dumpobj)
                              18426                 :                :                 {
 1972 andres@anarazel.de      18427                 :             39 :                     makeTableDataInfo(dopt, configtbl);
 4006 mail@joeconway.com      18428         [ +  - ]:             39 :                     if (configtbl->dataObj != NULL)
                              18429                 :                :                     {
                              18430         [ -  + ]:             39 :                         if (strlen(extconditionarray[j]) > 0)
 4006 mail@joeconway.com      18431                 :UBC           0 :                             configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
                              18432                 :                :                     }
                              18433                 :                :                 }
                              18434                 :                :             }
                              18435                 :                :         }
 4813 tgl@sss.pgh.pa.us       18436         [ +  + ]:CBC         174 :         if (extconfigarray)
                              18437                 :             20 :             free(extconfigarray);
                              18438         [ +  + ]:            174 :         if (extconditionarray)
                              18439                 :             20 :             free(extconditionarray);
                              18440                 :                :     }
                              18441                 :                : 
                              18442                 :                :     /*
                              18443                 :                :      * Now that all the TableDataInfo objects have been created for all the
                              18444                 :                :      * extensions, check their FK dependencies and register them to try and
                              18445                 :                :      * dump the data out in an order that they can be restored in.
                              18446                 :                :      *
                              18447                 :                :      * Note that this is not a problem for user tables as their FKs are
                              18448                 :                :      * recreated after the data has been loaded.
                              18449                 :                :      */
                              18450                 :                : 
 3014                         18451                 :            155 :     query = createPQExpBuffer();
                              18452                 :                : 
 3331 sfrost@snowman.net      18453                 :            155 :     printfPQExpBuffer(query,
                              18454                 :                :                       "SELECT conrelid, confrelid "
                              18455                 :                :                       "FROM pg_constraint "
                              18456                 :                :                       "JOIN pg_depend ON (objid = confrelid) "
                              18457                 :                :                       "WHERE contype = 'f' "
                              18458                 :                :                       "AND refclassid = 'pg_extension'::regclass "
                              18459                 :                :                       "AND classid = 'pg_class'::regclass;");
                              18460                 :                : 
                              18461                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              18462                 :            155 :     ntups = PQntuples(res);
                              18463                 :                : 
                              18464                 :            155 :     i_conrelid = PQfnumber(res, "conrelid");
                              18465                 :            155 :     i_confrelid = PQfnumber(res, "confrelid");
                              18466                 :                : 
                              18467                 :                :     /* Now get the dependencies and register them */
                              18468         [ -  + ]:            155 :     for (i = 0; i < ntups; i++)
                              18469                 :                :     {
                              18470                 :                :         Oid         conrelid,
                              18471                 :                :                     confrelid;
                              18472                 :                :         TableInfo  *reftable,
                              18473                 :                :                    *contable;
                              18474                 :                : 
 3331 sfrost@snowman.net      18475                 :UBC           0 :         conrelid = atooid(PQgetvalue(res, i, i_conrelid));
                              18476                 :              0 :         confrelid = atooid(PQgetvalue(res, i, i_confrelid));
                              18477                 :              0 :         contable = findTableByOid(conrelid);
                              18478                 :              0 :         reftable = findTableByOid(confrelid);
                              18479                 :                : 
                              18480         [ #  # ]:              0 :         if (reftable == NULL ||
                              18481   [ #  #  #  # ]:              0 :             reftable->dataObj == NULL ||
                              18482                 :              0 :             contable == NULL ||
                              18483         [ #  # ]:              0 :             contable->dataObj == NULL)
                              18484                 :              0 :             continue;
                              18485                 :                : 
                              18486                 :                :         /*
                              18487                 :                :          * Make referencing TABLE_DATA object depend on the referenced table's
                              18488                 :                :          * TABLE_DATA object.
                              18489                 :                :          */
                              18490                 :              0 :         addObjectDependency(&contable->dataObj->dobj,
                              18491                 :              0 :                             reftable->dataObj->dobj.dumpId);
                              18492                 :                :     }
 3199 tgl@sss.pgh.pa.us       18493                 :CBC         155 :     PQclear(res);
 4813                         18494                 :            155 :     destroyPQExpBuffer(query);
                              18495                 :                : }
                              18496                 :                : 
                              18497                 :                : /*
                              18498                 :                :  * getDependencies --- obtain available dependency data
                              18499                 :                :  */
                              18500                 :                : static void
 4451 rhaas@postgresql.org    18501                 :            155 : getDependencies(Archive *fout)
                              18502                 :                : {
                              18503                 :                :     PQExpBuffer query;
                              18504                 :                :     PGresult   *res;
                              18505                 :                :     int         ntups,
                              18506                 :                :                 i;
                              18507                 :                :     int         i_classid,
                              18508                 :                :                 i_objid,
                              18509                 :                :                 i_refclassid,
                              18510                 :                :                 i_refobjid,
                              18511                 :                :                 i_deptype;
                              18512                 :                :     DumpableObject *dobj,
                              18513                 :                :                *refdobj;
                              18514                 :                : 
 1840 peter@eisentraut.org    18515                 :            155 :     pg_log_info("reading dependency data");
                              18516                 :                : 
 7435 tgl@sss.pgh.pa.us       18517                 :            155 :     query = createPQExpBuffer();
                              18518                 :                : 
                              18519                 :                :     /*
                              18520                 :                :      * Messy query to collect the dependency data we need.  Note that we
                              18521                 :                :      * ignore the sub-object column, so that dependencies of or on a column
                              18522                 :                :      * look the same as dependencies of or on a whole table.
                              18523                 :                :      *
                              18524                 :                :      * PIN dependencies aren't interesting, and EXTENSION dependencies were
                              18525                 :                :      * already processed by getExtensionMembership.
                              18526                 :                :      */
 3800 heikki.linnakangas@i    18527                 :            155 :     appendPQExpBufferStr(query, "SELECT "
                              18528                 :                :                          "classid, objid, refclassid, refobjid, deptype "
                              18529                 :                :                          "FROM pg_depend "
                              18530                 :                :                          "WHERE deptype != 'p' AND deptype != 'e'\n");
                              18531                 :                : 
                              18532                 :                :     /*
                              18533                 :                :      * Since we don't treat pg_amop entries as separate DumpableObjects, we
                              18534                 :                :      * have to translate their dependencies into dependencies of their parent
                              18535                 :                :      * opfamily.  Ignore internal dependencies though, as those will point to
                              18536                 :                :      * their parent opclass, which we needn't consider here (and if we did,
                              18537                 :                :      * it'd just result in circular dependencies).  Also, "loose" opfamily
                              18538                 :                :      * entries will have dependencies on their parent opfamily, which we
                              18539                 :                :      * should drop since they'd likewise become useless self-dependencies.
                              18540                 :                :      * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.)
                              18541                 :                :      */
  852 tgl@sss.pgh.pa.us       18542                 :            155 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              18543                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype "
                              18544                 :                :                          "FROM pg_depend d, pg_amop o "
                              18545                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              18546                 :                :                          "classid = 'pg_amop'::regclass AND objid = o.oid "
                              18547                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n");
                              18548                 :                : 
                              18549                 :                :     /* Likewise for pg_amproc entries */
                              18550                 :            155 :     appendPQExpBufferStr(query, "UNION ALL\n"
                              18551                 :                :                          "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype "
                              18552                 :                :                          "FROM pg_depend d, pg_amproc p "
                              18553                 :                :                          "WHERE deptype NOT IN ('p', 'e', 'i') AND "
                              18554                 :                :                          "classid = 'pg_amproc'::regclass AND objid = p.oid "
                              18555                 :                :                          "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n");
                              18556                 :                : 
                              18557                 :                :     /* Sort the output for efficiency below */
 1719                         18558                 :            155 :     appendPQExpBufferStr(query, "ORDER BY 1,2");
                              18559                 :                : 
 4450 rhaas@postgresql.org    18560                 :            155 :     res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
                              18561                 :                : 
 7435 tgl@sss.pgh.pa.us       18562                 :            155 :     ntups = PQntuples(res);
                              18563                 :                : 
                              18564                 :            155 :     i_classid = PQfnumber(res, "classid");
                              18565                 :            155 :     i_objid = PQfnumber(res, "objid");
                              18566                 :            155 :     i_refclassid = PQfnumber(res, "refclassid");
                              18567                 :            155 :     i_refobjid = PQfnumber(res, "refobjid");
                              18568                 :            155 :     i_deptype = PQfnumber(res, "deptype");
                              18569                 :                : 
                              18570                 :                :     /*
                              18571                 :                :      * Since we ordered the SELECT by referencing ID, we can expect that
                              18572                 :                :      * multiple entries for the same object will appear together; this saves
                              18573                 :                :      * on searches.
                              18574                 :                :      */
                              18575                 :            155 :     dobj = NULL;
                              18576                 :                : 
                              18577         [ +  + ]:         323734 :     for (i = 0; i < ntups; i++)
                              18578                 :                :     {
                              18579                 :                :         CatalogId   objId;
                              18580                 :                :         CatalogId   refobjId;
                              18581                 :                :         char        deptype;
                              18582                 :                : 
                              18583                 :         323579 :         objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                              18584                 :         323579 :         objId.oid = atooid(PQgetvalue(res, i, i_objid));
                              18585                 :         323579 :         refobjId.tableoid = atooid(PQgetvalue(res, i, i_refclassid));
                              18586                 :         323579 :         refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
                              18587                 :         323579 :         deptype = *(PQgetvalue(res, i, i_deptype));
                              18588                 :                : 
                              18589         [ +  + ]:         323579 :         if (dobj == NULL ||
                              18590         [ +  + ]:         306712 :             dobj->catId.tableoid != objId.tableoid ||
                              18591         [ +  + ]:         304854 :             dobj->catId.oid != objId.oid)
                              18592                 :         137772 :             dobj = findObjectByCatalogId(objId);
                              18593                 :                : 
                              18594                 :                :         /*
                              18595                 :                :          * Failure to find objects mentioned in pg_depend is not unexpected,
                              18596                 :                :          * since for example we don't collect info about TOAST tables.
                              18597                 :                :          */
                              18598         [ +  + ]:         323579 :         if (dobj == NULL)
                              18599                 :                :         {
                              18600                 :                : #ifdef NOT_USED
                              18601                 :                :             pg_log_warning("no referencing object %u %u",
                              18602                 :                :                            objId.tableoid, objId.oid);
                              18603                 :                : #endif
                              18604                 :          17478 :             continue;
                              18605                 :                :         }
                              18606                 :                : 
                              18607                 :         306859 :         refdobj = findObjectByCatalogId(refobjId);
                              18608                 :                : 
                              18609         [ +  + ]:         306859 :         if (refdobj == NULL)
                              18610                 :                :         {
                              18611                 :                : #ifdef NOT_USED
                              18612                 :                :             pg_log_warning("no referenced object %u %u",
                              18613                 :                :                            refobjId.tableoid, refobjId.oid);
                              18614                 :                : #endif
                              18615                 :            758 :             continue;
                              18616                 :                :         }
                              18617                 :                : 
                              18618                 :                :         /*
                              18619                 :                :          * For 'x' dependencies, mark the object for later; we still add the
                              18620                 :                :          * normal dependency, for possible ordering purposes.  Currently
                              18621                 :                :          * pg_dump_sort.c knows to put extensions ahead of all object types
                              18622                 :                :          * that could possibly depend on them, but this is safer.
                              18623                 :                :          */
 1495 alvherre@alvh.no-ip.    18624         [ +  + ]:         306101 :         if (deptype == 'x')
                              18625                 :             44 :             dobj->depends_on_ext = true;
                              18626                 :                : 
                              18627                 :                :         /*
                              18628                 :                :          * Ordinarily, table rowtypes have implicit dependencies on their
                              18629                 :                :          * tables.  However, for a composite type the implicit dependency goes
                              18630                 :                :          * the other way in pg_depend; which is the right thing for DROP but
                              18631                 :                :          * it doesn't produce the dependency ordering we need. So in that one
                              18632                 :                :          * case, we reverse the direction of the dependency.
                              18633                 :                :          */
 7033 tgl@sss.pgh.pa.us       18634         [ +  + ]:         306101 :         if (deptype == 'i' &&
                              18635         [ +  + ]:          84153 :             dobj->objType == DO_TABLE &&
                              18636         [ +  + ]:            884 :             refdobj->objType == DO_TYPE)
                              18637                 :            151 :             addObjectDependency(refdobj, dobj->dumpId);
                              18638                 :                :         else
                              18639                 :                :             /* normal case */
                              18640                 :         305950 :             addObjectDependency(dobj, refdobj->dumpId);
                              18641                 :                :     }
                              18642                 :                : 
 7435                         18643                 :            155 :     PQclear(res);
                              18644                 :                : 
 8290                         18645                 :            155 :     destroyPQExpBuffer(query);
 9322 bruce@momjian.us        18646                 :            155 : }
                              18647                 :                : 
                              18648                 :                : 
                              18649                 :                : /*
                              18650                 :                :  * createBoundaryObjects - create dummy DumpableObjects to represent
                              18651                 :                :  * dump section boundaries.
                              18652                 :                :  */
                              18653                 :                : static DumpableObject *
 4311 tgl@sss.pgh.pa.us       18654                 :            155 : createBoundaryObjects(void)
                              18655                 :                : {
                              18656                 :                :     DumpableObject *dobjs;
                              18657                 :                : 
                              18658                 :            155 :     dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
                              18659                 :                : 
                              18660                 :            155 :     dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
                              18661                 :            155 :     dobjs[0].catId = nilCatalogId;
                              18662                 :            155 :     AssignDumpId(dobjs + 0);
                              18663                 :            155 :     dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
                              18664                 :                : 
                              18665                 :            155 :     dobjs[1].objType = DO_POST_DATA_BOUNDARY;
                              18666                 :            155 :     dobjs[1].catId = nilCatalogId;
                              18667                 :            155 :     AssignDumpId(dobjs + 1);
                              18668                 :            155 :     dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
                              18669                 :                : 
                              18670                 :            155 :     return dobjs;
                              18671                 :                : }
                              18672                 :                : 
                              18673                 :                : /*
                              18674                 :                :  * addBoundaryDependencies - add dependencies as needed to enforce the dump
                              18675                 :                :  * section boundaries.
                              18676                 :                :  */
                              18677                 :                : static void
                              18678                 :            155 : addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
                              18679                 :                :                         DumpableObject *boundaryObjs)
                              18680                 :                : {
                              18681                 :            155 :     DumpableObject *preDataBound = boundaryObjs + 0;
                              18682                 :            155 :     DumpableObject *postDataBound = boundaryObjs + 1;
                              18683                 :                :     int         i;
                              18684                 :                : 
                              18685         [ +  + ]:         664403 :     for (i = 0; i < numObjs; i++)
                              18686                 :                :     {
                              18687                 :         664248 :         DumpableObject *dobj = dobjs[i];
                              18688                 :                : 
                              18689                 :                :         /*
                              18690                 :                :          * The classification of object types here must match the SECTION_xxx
                              18691                 :                :          * values assigned during subsequent ArchiveEntry calls!
                              18692                 :                :          */
                              18693   [ +  +  +  +  :         664248 :         switch (dobj->objType)
                                        +  +  +  - ]
                              18694                 :                :         {
                              18695                 :         629249 :             case DO_NAMESPACE:
                              18696                 :                :             case DO_EXTENSION:
                              18697                 :                :             case DO_TYPE:
                              18698                 :                :             case DO_SHELL_TYPE:
                              18699                 :                :             case DO_FUNC:
                              18700                 :                :             case DO_AGG:
                              18701                 :                :             case DO_OPERATOR:
                              18702                 :                :             case DO_ACCESS_METHOD:
                              18703                 :                :             case DO_OPCLASS:
                              18704                 :                :             case DO_OPFAMILY:
                              18705                 :                :             case DO_COLLATION:
                              18706                 :                :             case DO_CONVERSION:
                              18707                 :                :             case DO_TABLE:
                              18708                 :                :             case DO_TABLE_ATTACH:
                              18709                 :                :             case DO_ATTRDEF:
                              18710                 :                :             case DO_PROCLANG:
                              18711                 :                :             case DO_CAST:
                              18712                 :                :             case DO_DUMMY_TYPE:
                              18713                 :                :             case DO_TSPARSER:
                              18714                 :                :             case DO_TSDICT:
                              18715                 :                :             case DO_TSTEMPLATE:
                              18716                 :                :             case DO_TSCONFIG:
                              18717                 :                :             case DO_FDW:
                              18718                 :                :             case DO_FOREIGN_SERVER:
                              18719                 :                :             case DO_TRANSFORM:
                              18720                 :                :                 /* Pre-data objects: must come before the pre-data boundary */
                              18721                 :         629249 :                 addObjectDependency(preDataBound, dobj->dumpId);
                              18722                 :         629249 :                 break;
                              18723                 :           4159 :             case DO_TABLE_DATA:
                              18724                 :                :             case DO_SEQUENCE_SET:
                              18725                 :                :             case DO_LARGE_OBJECT:
                              18726                 :                :             case DO_LARGE_OBJECT_DATA:
                              18727                 :                :                 /* Data objects: must come between the boundaries */
                              18728                 :           4159 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              18729                 :           4159 :                 addObjectDependency(postDataBound, dobj->dumpId);
                              18730                 :           4159 :                 break;
                              18731                 :           5069 :             case DO_INDEX:
                              18732                 :                :             case DO_INDEX_ATTACH:
                              18733                 :                :             case DO_STATSEXT:
                              18734                 :                :             case DO_REFRESH_MATVIEW:
                              18735                 :                :             case DO_TRIGGER:
                              18736                 :                :             case DO_EVENT_TRIGGER:
                              18737                 :                :             case DO_DEFAULT_ACL:
                              18738                 :                :             case DO_POLICY:
                              18739                 :                :             case DO_PUBLICATION:
                              18740                 :                :             case DO_PUBLICATION_REL:
                              18741                 :                :             case DO_PUBLICATION_TABLE_IN_SCHEMA:
                              18742                 :                :             case DO_SUBSCRIPTION:
                              18743                 :                :             case DO_SUBSCRIPTION_REL:
                              18744                 :                :                 /* Post-data objects: must come after the post-data boundary */
                              18745                 :           5069 :                 addObjectDependency(dobj, postDataBound->dumpId);
                              18746                 :           5069 :                 break;
                              18747                 :          23405 :             case DO_RULE:
                              18748                 :                :                 /* Rules are post-data, but only if dumped separately */
                              18749         [ +  + ]:          23405 :                 if (((RuleInfo *) dobj)->separate)
                              18750                 :            505 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              18751                 :          23405 :                 break;
                              18752                 :           2056 :             case DO_CONSTRAINT:
                              18753                 :                :             case DO_FK_CONSTRAINT:
                              18754                 :                :                 /* Constraints are post-data, but only if dumped separately */
                              18755         [ +  + ]:           2056 :                 if (((ConstraintInfo *) dobj)->separate)
                              18756                 :           1424 :                     addObjectDependency(dobj, postDataBound->dumpId);
                              18757                 :           2056 :                 break;
                              18758                 :            155 :             case DO_PRE_DATA_BOUNDARY:
                              18759                 :                :                 /* nothing to do */
                              18760                 :            155 :                 break;
                              18761                 :            155 :             case DO_POST_DATA_BOUNDARY:
                              18762                 :                :                 /* must come after the pre-data boundary */
                              18763                 :            155 :                 addObjectDependency(dobj, preDataBound->dumpId);
                              18764                 :            155 :                 break;
                              18765                 :                :         }
                              18766                 :                :     }
                              18767                 :            155 : }
                              18768                 :                : 
                              18769                 :                : 
                              18770                 :                : /*
                              18771                 :                :  * BuildArchiveDependencies - create dependency data for archive TOC entries
                              18772                 :                :  *
                              18773                 :                :  * The raw dependency data obtained by getDependencies() is not terribly
                              18774                 :                :  * useful in an archive dump, because in many cases there are dependency
                              18775                 :                :  * chains linking through objects that don't appear explicitly in the dump.
                              18776                 :                :  * For example, a view will depend on its _RETURN rule while the _RETURN rule
                              18777                 :                :  * will depend on other objects --- but the rule will not appear as a separate
                              18778                 :                :  * object in the dump.  We need to adjust the view's dependencies to include
                              18779                 :                :  * whatever the rule depends on that is included in the dump.
                              18780                 :                :  *
                              18781                 :                :  * Just to make things more complicated, there are also "special" dependencies
                              18782                 :                :  * such as the dependency of a TABLE DATA item on its TABLE, which we must
                              18783                 :                :  * not rearrange because pg_restore knows that TABLE DATA only depends on
                              18784                 :                :  * its table.  In these cases we must leave the dependencies strictly as-is
                              18785                 :                :  * even if they refer to not-to-be-dumped objects.
                              18786                 :                :  *
                              18787                 :                :  * To handle this, the convention is that "special" dependencies are created
                              18788                 :                :  * during ArchiveEntry calls, and an archive TOC item that has any such
                              18789                 :                :  * entries will not be touched here.  Otherwise, we recursively search the
                              18790                 :                :  * DumpableObject data structures to build the correct dependencies for each
                              18791                 :                :  * archive TOC item.
                              18792                 :                :  */
                              18793                 :                : static void
                              18794                 :             33 : BuildArchiveDependencies(Archive *fout)
                              18795                 :                : {
                              18796                 :             33 :     ArchiveHandle *AH = (ArchiveHandle *) fout;
                              18797                 :                :     TocEntry   *te;
                              18798                 :                : 
                              18799                 :                :     /* Scan all TOC entries in the archive */
                              18800         [ +  + ]:           5428 :     for (te = AH->toc->next; te != AH->toc; te = te->next)
                              18801                 :                :     {
                              18802                 :                :         DumpableObject *dobj;
                              18803                 :                :         DumpId     *dependencies;
                              18804                 :                :         int         nDeps;
                              18805                 :                :         int         allocDeps;
                              18806                 :                : 
                              18807                 :                :         /* No need to process entries that will not be dumped */
                              18808         [ +  + ]:           5395 :         if (te->reqs == 0)
                              18809                 :           1745 :             continue;
                              18810                 :                :         /* Ignore entries that already have "special" dependencies */
                              18811         [ +  + ]:           5392 :         if (te->nDeps > 0)
                              18812                 :           1451 :             continue;
                              18813                 :                :         /* Otherwise, look up the item's original DumpableObject, if any */
                              18814                 :           3941 :         dobj = findObjectByDumpId(te->dumpId);
                              18815         [ +  + ]:           3941 :         if (dobj == NULL)
                              18816                 :            169 :             continue;
                              18817                 :                :         /* No work if it has no dependencies */
                              18818         [ +  + ]:           3772 :         if (dobj->nDeps <= 0)
                              18819                 :            122 :             continue;
                              18820                 :                :         /* Set up work array */
                              18821                 :           3650 :         allocDeps = 64;
                              18822                 :           3650 :         dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
                              18823                 :           3650 :         nDeps = 0;
                              18824                 :                :         /* Recursively find all dumpable dependencies */
                              18825                 :           3650 :         findDumpableDependencies(AH, dobj,
                              18826                 :                :                                  &dependencies, &nDeps, &allocDeps);
                              18827                 :                :         /* And save 'em ... */
                              18828         [ +  + ]:           3650 :         if (nDeps > 0)
                              18829                 :                :         {
                              18830                 :           2812 :             dependencies = (DumpId *) pg_realloc(dependencies,
                              18831                 :                :                                                  nDeps * sizeof(DumpId));
                              18832                 :           2812 :             te->dependencies = dependencies;
                              18833                 :           2812 :             te->nDeps = nDeps;
                              18834                 :                :         }
                              18835                 :                :         else
                              18836                 :            838 :             free(dependencies);
                              18837                 :                :     }
                              18838                 :             33 : }
                              18839                 :                : 
                              18840                 :                : /* Recursive search subroutine for BuildArchiveDependencies */
                              18841                 :                : static void
 1159 peter@eisentraut.org    18842                 :           8803 : findDumpableDependencies(ArchiveHandle *AH, const DumpableObject *dobj,
                              18843                 :                :                          DumpId **dependencies, int *nDeps, int *allocDeps)
                              18844                 :                : {
                              18845                 :                :     int         i;
                              18846                 :                : 
                              18847                 :                :     /*
                              18848                 :                :      * Ignore section boundary objects: if we search through them, we'll
                              18849                 :                :      * report lots of bogus dependencies.
                              18850                 :                :      */
 4311 tgl@sss.pgh.pa.us       18851         [ +  + ]:           8803 :     if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
                              18852         [ +  + ]:           8780 :         dobj->objType == DO_POST_DATA_BOUNDARY)
                              18853                 :           1614 :         return;
                              18854                 :                : 
                              18855         [ +  + ]:          18407 :     for (i = 0; i < dobj->nDeps; i++)
                              18856                 :                :     {
                              18857                 :          11218 :         DumpId      depid = dobj->dependencies[i];
                              18858                 :                : 
                              18859         [ +  + ]:          11218 :         if (TocIDRequired(AH, depid) != 0)
                              18860                 :                :         {
                              18861                 :                :             /* Object will be dumped, so just reference it as a dependency */
                              18862         [ -  + ]:           6065 :             if (*nDeps >= *allocDeps)
                              18863                 :                :             {
 4311 tgl@sss.pgh.pa.us       18864                 :UBC           0 :                 *allocDeps *= 2;
                              18865                 :              0 :                 *dependencies = (DumpId *) pg_realloc(*dependencies,
 2489                         18866                 :              0 :                                                       *allocDeps * sizeof(DumpId));
                              18867                 :                :             }
 4311 tgl@sss.pgh.pa.us       18868                 :CBC        6065 :             (*dependencies)[*nDeps] = depid;
                              18869                 :           6065 :             (*nDeps)++;
                              18870                 :                :         }
                              18871                 :                :         else
                              18872                 :                :         {
                              18873                 :                :             /*
                              18874                 :                :              * Object will not be dumped, so recursively consider its deps. We
                              18875                 :                :              * rely on the assumption that sortDumpableObjects already broke
                              18876                 :                :              * any dependency loops, else we might recurse infinitely.
                              18877                 :                :              */
                              18878                 :           5153 :             DumpableObject *otherdobj = findObjectByDumpId(depid);
                              18879                 :                : 
                              18880         [ +  - ]:           5153 :             if (otherdobj)
                              18881                 :           5153 :                 findDumpableDependencies(AH, otherdobj,
                              18882                 :                :                                          dependencies, nDeps, allocDeps);
                              18883                 :                :         }
                              18884                 :                :     }
                              18885                 :                : }
                              18886                 :                : 
                              18887                 :                : 
                              18888                 :                : /*
                              18889                 :                :  * getFormattedTypeName - retrieve a nicely-formatted type name for the
                              18890                 :                :  * given type OID.
                              18891                 :                :  *
                              18892                 :                :  * This does not guarantee to schema-qualify the output, so it should not
                              18893                 :                :  * be used to create the target object name for CREATE or ALTER commands.
                              18894                 :                :  *
                              18895                 :                :  * Note that the result is cached and must not be freed by the caller.
                              18896                 :                :  */
                              18897                 :                : static const char *
 4451 rhaas@postgresql.org    18898                 :           2310 : getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
                              18899                 :                : {
                              18900                 :                :     TypeInfo   *typeInfo;
                              18901                 :                :     char       *result;
                              18902                 :                :     PQExpBuffer query;
                              18903                 :                :     PGresult   *res;
                              18904                 :                : 
 7435 tgl@sss.pgh.pa.us       18905         [ -  + ]:           2310 :     if (oid == 0)
                              18906                 :                :     {
 1501 tgl@sss.pgh.pa.us       18907         [ #  # ]:UBC           0 :         if ((opts & zeroAsStar) != 0)
  949                         18908                 :              0 :             return "*";
 8010                         18909         [ #  # ]:              0 :         else if ((opts & zeroAsNone) != 0)
  949                         18910                 :              0 :             return "NONE";
                              18911                 :                :     }
                              18912                 :                : 
                              18913                 :                :     /* see if we have the result cached in the type's TypeInfo record */
  957 tgl@sss.pgh.pa.us       18914                 :CBC        2310 :     typeInfo = findTypeByOid(oid);
                              18915   [ +  -  +  + ]:           2310 :     if (typeInfo && typeInfo->ftypname)
  949                         18916                 :           1827 :         return typeInfo->ftypname;
                              18917                 :                : 
 8010                         18918                 :            483 :     query = createPQExpBuffer();
 2741                         18919                 :            483 :     appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
                              18920                 :                :                       oid);
                              18921                 :                : 
 4441 rhaas@postgresql.org    18922                 :            483 :     res = ExecuteSqlQueryForSingleRow(fout, query->data);
                              18923                 :                : 
                              18924                 :                :     /* result of format_type is already quoted */
 2741 tgl@sss.pgh.pa.us       18925                 :            483 :     result = pg_strdup(PQgetvalue(res, 0, 0));
                              18926                 :                : 
 8010                         18927                 :            483 :     PQclear(res);
                              18928                 :            483 :     destroyPQExpBuffer(query);
                              18929                 :                : 
                              18930                 :                :     /*
                              18931                 :                :      * Cache the result for re-use in later requests, if possible.  If we
                              18932                 :                :      * don't have a TypeInfo for the type, the string will be leaked once the
                              18933                 :                :      * caller is done with it ... but that case really should not happen, so
                              18934                 :                :      * leaking if it does seems acceptable.
                              18935                 :                :      */
  957                         18936         [ +  - ]:            483 :     if (typeInfo)
  949                         18937                 :            483 :         typeInfo->ftypname = result;
                              18938                 :                : 
 8010                         18939                 :            483 :     return result;
                              18940                 :                : }
                              18941                 :                : 
                              18942                 :                : /*
                              18943                 :                :  * Return a column list clause for the given relation.
                              18944                 :                :  *
                              18945                 :                :  * Special case: if there are no undropped columns in the relation, return
                              18946                 :                :  * "", not an invalid "()" column list.
                              18947                 :                :  */
                              18948                 :                : static const char *
 4039 andrew@dunslane.net     18949                 :           7026 : fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
                              18950                 :                : {
 7941 bruce@momjian.us        18951                 :           7026 :     int         numatts = ti->numatts;
 7893                         18952                 :           7026 :     char      **attnames = ti->attnames;
                              18953                 :           7026 :     bool       *attisdropped = ti->attisdropped;
 1842 peter@eisentraut.org    18954                 :           7026 :     char       *attgenerated = ti->attgenerated;
                              18955                 :                :     bool        needComma;
                              18956                 :                :     int         i;
                              18957                 :                : 
 3800 heikki.linnakangas@i    18958                 :           7026 :     appendPQExpBufferChar(buffer, '(');
 7926 tgl@sss.pgh.pa.us       18959                 :           7026 :     needComma = false;
 7941 bruce@momjian.us        18960         [ +  + ]:          34286 :     for (i = 0; i < numatts; i++)
                              18961                 :                :     {
 7926 tgl@sss.pgh.pa.us       18962         [ +  + ]:          27260 :         if (attisdropped[i])
                              18963                 :            564 :             continue;
 1842 peter@eisentraut.org    18964         [ +  + ]:          26696 :         if (attgenerated[i])
                              18965                 :            620 :             continue;
 7926 tgl@sss.pgh.pa.us       18966         [ +  + ]:          26076 :         if (needComma)
 3800 heikki.linnakangas@i    18967                 :          19284 :             appendPQExpBufferStr(buffer, ", ");
                              18968                 :          26076 :         appendPQExpBufferStr(buffer, fmtId(attnames[i]));
 7926 tgl@sss.pgh.pa.us       18969                 :          26076 :         needComma = true;
                              18970                 :                :     }
                              18971                 :                : 
 7794                         18972         [ +  + ]:           7026 :     if (!needComma)
 7660                         18973                 :            234 :         return "";                /* no undropped columns */
                              18974                 :                : 
 3800 heikki.linnakangas@i    18975                 :           6792 :     appendPQExpBufferChar(buffer, ')');
 4039 andrew@dunslane.net     18976                 :           6792 :     return buffer->data;
                              18977                 :                : }
                              18978                 :                : 
                              18979                 :                : /*
                              18980                 :                :  * Check if a reloptions array is nonempty.
                              18981                 :                :  */
                              18982                 :                : static bool
 3025 tgl@sss.pgh.pa.us       18983                 :          11801 : nonemptyReloptions(const char *reloptions)
                              18984                 :                : {
                              18985                 :                :     /* Don't want to print it if it's just "{}" */
                              18986   [ +  -  +  + ]:          11801 :     return (reloptions != NULL && strlen(reloptions) > 2);
                              18987                 :                : }
                              18988                 :                : 
                              18989                 :                : /*
                              18990                 :                :  * Format a reloptions array and append it to the given buffer.
                              18991                 :                :  *
                              18992                 :                :  * "prefix" is prepended to the option names; typically it's "" or "toast.".
                              18993                 :                :  */
                              18994                 :                : static void
 2900 dean.a.rasheed@gmail    18995                 :            210 : appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions,
                              18996                 :                :                         const char *prefix, Archive *fout)
                              18997                 :                : {
                              18998                 :                :     bool        res;
                              18999                 :                : 
                              19000                 :            210 :     res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding,
                              19001                 :            210 :                                 fout->std_strings);
                              19002         [ -  + ]:            210 :     if (!res)
  897 peter@eisentraut.org    19003                 :UBC           0 :         pg_log_warning("could not parse %s array", "reloptions");
 3025 tgl@sss.pgh.pa.us       19004                 :CBC         210 : }
                              19005                 :                : 
                              19006                 :                : /*
                              19007                 :                :  * read_dump_filters - retrieve object identifier patterns from file
                              19008                 :                :  *
                              19009                 :                :  * Parse the specified filter file for include and exclude patterns, and add
                              19010                 :                :  * them to the relevant lists.  If the filename is "-" then filters will be
                              19011                 :                :  * read from STDIN rather than a file.
                              19012                 :                :  */
                              19013                 :                : static void
  137 dgustafsson@postgres    19014                 :GNC          26 : read_dump_filters(const char *filename, DumpOptions *dopt)
                              19015                 :                : {
                              19016                 :                :     FilterStateData fstate;
                              19017                 :                :     char       *objname;
                              19018                 :                :     FilterCommandType comtype;
                              19019                 :                :     FilterObjectType objtype;
                              19020                 :                : 
                              19021                 :             26 :     filter_init(&fstate, filename, exit_nicely);
                              19022                 :                : 
                              19023         [ +  + ]:             84 :     while (filter_read_item(&fstate, &objname, &comtype, &objtype))
                              19024                 :                :     {
                              19025         [ +  + ]:             33 :         if (comtype == FILTER_COMMAND_TYPE_INCLUDE)
                              19026                 :                :         {
                              19027   [ -  -  +  +  :             17 :             switch (objtype)
                                        +  +  +  - ]
                              19028                 :                :             {
  137 dgustafsson@postgres    19029                 :UNC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              19030                 :              0 :                     break;
                              19031                 :              0 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              19032                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              19033                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              19034                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              19035                 :                :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              19036                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
  136                         19037                 :              0 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              19038                 :                :                                         "include",
                              19039                 :                :                                         filter_object_type_name(objtype));
  137                         19040                 :              0 :                     exit_nicely(1);
                              19041                 :                :                     break;      /* unreachable */
                              19042                 :                : 
  137 dgustafsson@postgres    19043                 :GNC           1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              19044                 :              1 :                     simple_string_list_append(&extension_include_patterns, objname);
                              19045                 :              1 :                     break;
                              19046                 :              1 :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
                              19047                 :              1 :                     simple_string_list_append(&foreign_servers_include_patterns, objname);
                              19048                 :              1 :                     break;
                              19049                 :              1 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              19050                 :              1 :                     simple_string_list_append(&schema_include_patterns, objname);
                              19051                 :              1 :                     dopt->include_everything = false;
                              19052                 :              1 :                     break;
                              19053                 :             13 :                 case FILTER_OBJECT_TYPE_TABLE:
                              19054                 :             13 :                     simple_string_list_append(&table_include_patterns, objname);
                              19055                 :             13 :                     dopt->include_everything = false;
                              19056                 :             13 :                     break;
                              19057                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              19058                 :              1 :                     simple_string_list_append(&table_include_patterns_and_children,
                              19059                 :                :                                               objname);
                              19060                 :              1 :                     dopt->include_everything = false;
                              19061                 :              1 :                     break;
                              19062                 :                :             }
                              19063                 :                :         }
                              19064         [ +  + ]:             16 :         else if (comtype == FILTER_COMMAND_TYPE_EXCLUDE)
                              19065                 :                :         {
                              19066   [ -  +  +  +  :              9 :             switch (objtype)
                                        +  +  +  +  
                                                 - ]
                              19067                 :                :             {
  137 dgustafsson@postgres    19068                 :UNC           0 :                 case FILTER_OBJECT_TYPE_NONE:
                              19069                 :              0 :                     break;
  137 dgustafsson@postgres    19070                 :GNC           1 :                 case FILTER_OBJECT_TYPE_DATABASE:
                              19071                 :                :                 case FILTER_OBJECT_TYPE_FUNCTION:
                              19072                 :                :                 case FILTER_OBJECT_TYPE_INDEX:
                              19073                 :                :                 case FILTER_OBJECT_TYPE_TRIGGER:
                              19074                 :                :                 case FILTER_OBJECT_TYPE_FOREIGN_DATA:
  136                         19075                 :              1 :                     pg_log_filter_error(&fstate, _("%s filter for \"%s\" is not allowed"),
                              19076                 :                :                                         "exclude",
                              19077                 :                :                                         filter_object_type_name(objtype));
  137                         19078                 :              1 :                     exit_nicely(1);
                              19079                 :                :                     break;
                              19080                 :                : 
   25 dean.a.rasheed@gmail    19081                 :              1 :                 case FILTER_OBJECT_TYPE_EXTENSION:
                              19082                 :              1 :                     simple_string_list_append(&extension_exclude_patterns, objname);
                              19083                 :              1 :                     break;
  137 dgustafsson@postgres    19084                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA:
                              19085                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns,
                              19086                 :                :                                               objname);
                              19087                 :              1 :                     break;
                              19088                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_DATA_AND_CHILDREN:
                              19089                 :              1 :                     simple_string_list_append(&tabledata_exclude_patterns_and_children,
                              19090                 :                :                                               objname);
                              19091                 :              1 :                     break;
                              19092                 :              2 :                 case FILTER_OBJECT_TYPE_SCHEMA:
                              19093                 :              2 :                     simple_string_list_append(&schema_exclude_patterns, objname);
                              19094                 :              2 :                     break;
                              19095                 :              2 :                 case FILTER_OBJECT_TYPE_TABLE:
                              19096                 :              2 :                     simple_string_list_append(&table_exclude_patterns, objname);
                              19097                 :              2 :                     break;
                              19098                 :              1 :                 case FILTER_OBJECT_TYPE_TABLE_AND_CHILDREN:
                              19099                 :              1 :                     simple_string_list_append(&table_exclude_patterns_and_children,
                              19100                 :                :                                               objname);
                              19101                 :              1 :                     break;
                              19102                 :                :             }
                              19103                 :                :         }
                              19104                 :                :         else
                              19105                 :                :         {
                              19106         [ -  + ]:              7 :             Assert(comtype == FILTER_COMMAND_TYPE_NONE);
                              19107         [ -  + ]:              7 :             Assert(objtype == FILTER_OBJECT_TYPE_NONE);
                              19108                 :                :         }
                              19109                 :                : 
                              19110         [ +  + ]:             32 :         if (objname)
                              19111                 :             25 :             free(objname);
                              19112                 :                :     }
                              19113                 :                : 
                              19114                 :             22 :     filter_free(&fstate);
                              19115                 :             22 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622