]> granicus.if.org Git - postgresql/blobdiff - src/bin/pg_dump/pg_dump.c
Allow polymorphic aggregates to have non-polymorphic state data types.
[postgresql] / src / bin / pg_dump / pg_dump.c
index 8db4071684780ca5c34f3089fbb02564e220f27e..c2bb6161b214811d38af43f480e5bb517d4db0c1 100644 (file)
@@ -4,7 +4,7 @@
  *       pg_dump is a utility for dumping out a postgres database
  *       into a script file.
  *
- * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *     pg_dump will read the system catalogs in a database and dump out a
  *     Note that pg_dump runs in a transaction-snapshot mode transaction,
  *     so it sees a consistent snapshot of the database including system
  *     catalogs. However, it relies in part on various specialized backend
- *     functions like pg_get_indexdef(), and those things tend to run on
- *     SnapshotNow time, ie they look at the currently committed state.  So
- *     it is possible to get 'cache lookup failed' error if someone
- *     performs DDL changes while a dump is happening. The window for this
- *     sort of thing is from the acquisition of the transaction snapshot to
- *     getSchemaData() (when pg_dump acquires AccessShareLock on every
- *     table it intends to dump). It isn't very large, but it can happen.
+ *     functions like pg_get_indexdef(), and those things tend to look at
+ *     the currently committed state.  So it is possible to get 'cache
+ *     lookup failed' error if someone performs DDL changes while a dump is
+ *     happening. The window for this sort of thing is from the acquisition
+ *     of the transaction snapshot to getSchemaData() (when pg_dump acquires
+ *     AccessShareLock on every table it intends to dump). It isn't very large,
+ *     but it can happen.
  *
  *     http://archives.postgresql.org/pgsql-bugs/2010-02/msg00187.php
  *
@@ -49,6 +49,7 @@
 #include "catalog/pg_cast.h"
 #include "catalog/pg_class.h"
 #include "catalog/pg_default_acl.h"
+#include "catalog/pg_event_trigger.h"
 #include "catalog/pg_largeobject.h"
 #include "catalog/pg_largeobject_metadata.h"
 #include "catalog/pg_proc.h"
 #include "libpq/libpq-fs.h"
 
 #include "pg_backup_archiver.h"
-#include "dumpmem.h"
+#include "pg_backup_db.h"
+#include "pg_backup_utils.h"
 #include "dumputils.h"
-
-extern char *optarg;
-extern int     optind,
-                       opterr;
+#include "parallel.h"
 
 
 typedef struct
@@ -85,15 +84,13 @@ typedef struct
 /* global decls */
 bool           g_verbose;                      /* User wants verbose narration of our
                                                                 * activities. */
-Archive    *g_fout;                            /* the script file */
-PGconn    *g_conn;                             /* the database connection */
 
 /* various user-settable parameters */
-bool           schemaOnly;
-bool           dataOnly;
-int         dumpSections; /* bitmask of chosen sections */
-bool           aclsSkip;
-const char *lockWaitTimeout;
+static bool    schemaOnly;
+static bool    dataOnly;
+static int     dumpSections;           /* bitmask of chosen sections */
+static bool    aclsSkip;
+static const char *lockWaitTimeout;
 
 /* subquery used to convert user ID (eg, datdba) to user name */
 static const char *username_subquery;
@@ -130,28 +127,31 @@ char              g_comment_end[10];
 
 static const CatalogId nilCatalogId = {0, 0};
 
-/* these are to avoid passing around info for findNamespace() */
-static NamespaceInfo *g_namespaces;
-static int     g_numNamespaces;
-
 /* flags for various command-line long options */
 static int     binary_upgrade = 0;
 static int     disable_dollar_quoting = 0;
 static int     dump_inserts = 0;
 static int     column_inserts = 0;
+static int     if_exists = 0;
 static int     no_security_labels = 0;
+static int     no_synchronized_snapshots = 0;
 static int     no_unlogged_table_data = 0;
 static int     serializable_deferrable = 0;
 
 
 static void help(const char *progname);
+static void setup_connection(Archive *AH, const char *dumpencoding,
+                                char *use_role);
 static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
-static void expand_schema_name_patterns(SimpleStringList *patterns,
+static void expand_schema_name_patterns(Archive *fout,
+                                                       SimpleStringList *patterns,
                                                        SimpleOidList *oids);
-static void expand_table_name_patterns(SimpleStringList *patterns,
+static void expand_table_name_patterns(Archive *fout,
+                                                  SimpleStringList *patterns,
                                                   SimpleOidList *oids);
-static NamespaceInfo *findNamespace(Oid nsoid, Oid objoid);
+static NamespaceInfo *findNamespace(Archive *fout, Oid nsoid, Oid objoid);
 static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
+static void refreshMatViewData(Archive *fout, TableDataInfo *tdinfo);
 static void guessConstraintInheritance(TableInfo *tblinfo, int numTables);
 static void dumpComment(Archive *fout, const char *target,
                        const char *namespace, const char *owner,
@@ -187,10 +187,12 @@ static void dumpConversion(Archive *fout, ConvInfo *convinfo);
 static void dumpRule(Archive *fout, RuleInfo *rinfo);
 static void dumpAgg(Archive *fout, AggInfo *agginfo);
 static void dumpTrigger(Archive *fout, TriggerInfo *tginfo);
+static void dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo);
 static void dumpTable(Archive *fout, TableInfo *tbinfo);
 static void dumpTableSchema(Archive *fout, TableInfo *tbinfo);
 static void dumpAttrDef(Archive *fout, AttrDefInfo *adinfo);
 static void dumpSequence(Archive *fout, TableInfo *tbinfo);
+static void dumpSequenceData(Archive *fout, TableDataInfo *tdinfo);
 static void dumpIndex(Archive *fout, IndxInfo *indxinfo);
 static void dumpConstraint(Archive *fout, ConstraintInfo *coninfo);
 static void dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo);
@@ -210,46 +212,60 @@ static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
                const char *tag, const char *nspname, const char *owner,
                const char *acls);
 
-static void getDependencies(void);
-static void getDomainConstraints(TypeInfo *tyinfo);
+static void getDependencies(Archive *fout);
+static void BuildArchiveDependencies(Archive *fout);
+static void findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
+                                                DumpId **dependencies, int *nDeps, int *allocDeps);
+
+static DumpableObject *createBoundaryObjects(void);
+static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
+                                               DumpableObject *boundaryObjs);
+
+static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
 static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
 static void makeTableDataInfo(TableInfo *tbinfo, bool oids);
+static void buildMatViewRefreshDependencies(Archive *fout);
 static void getTableDataFKConstraints(void);
-static char *format_function_arguments(FuncInfo *finfo, char *funcargs);
-static char *format_function_arguments_old(FuncInfo *finfo, int nallargs,
+static char *format_function_arguments(FuncInfo *finfo, char *funcargs,
+                                                                          bool is_agg);
+static char *format_function_arguments_old(Archive *fout,
+                                                         FuncInfo *finfo, int nallargs,
                                                          char **allargtypes,
                                                          char **argmodes,
                                                          char **argnames);
-static char *format_function_signature(FuncInfo *finfo, bool honor_quotes);
-static const char *convertRegProcReference(const char *proc);
-static const char *convertOperatorReference(const char *opr);
-static const char *convertTSFunction(Oid funcOid);
-static Oid     findLastBuiltinOid_V71(const char *);
-static Oid     findLastBuiltinOid_V70(void);
-static void selectSourceSchema(const char *schemaName);
-static char *getFormattedTypeName(Oid oid, OidOptions opts);
+static char *format_function_signature(Archive *fout,
+                                                 FuncInfo *finfo, bool honor_quotes);
+static char *convertRegProcReference(Archive *fout,
+                                               const char *proc);
+static char *convertOperatorReference(Archive *fout, const char *opr);
+static const char *convertTSFunction(Archive *fout, Oid funcOid);
+static Oid     findLastBuiltinOid_V71(Archive *fout, const char *);
+static Oid     findLastBuiltinOid_V70(Archive *fout);
+static void selectSourceSchema(Archive *fout, const char *schemaName);
+static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts);
 static char *myFormatType(const char *typname, int32 typmod);
-static const char *fmtQualifiedId(const char *schema, const char *id);
-static void getBlobs(Archive *AH);
-static void dumpBlob(Archive *AH, BlobInfo *binfo);
-static int     dumpBlobs(Archive *AH, void *arg);
+static void getBlobs(Archive *fout);
+static void dumpBlob(Archive *fout, BlobInfo *binfo);
+static int     dumpBlobs(Archive *fout, void *arg);
 static void dumpDatabase(Archive *AH);
 static void dumpEncoding(Archive *AH);
 static void dumpStdStrings(Archive *AH);
-static void binary_upgrade_set_type_oids_by_type_oid(
+static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
                                                                PQExpBuffer upgrade_buffer, Oid pg_type_oid);
-static bool binary_upgrade_set_type_oids_by_rel_oid(
+static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
                                                                 PQExpBuffer upgrade_buffer, Oid pg_rel_oid);
-static void binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer,
+static void binary_upgrade_set_pg_class_oids(Archive *fout,
+                                                                PQExpBuffer upgrade_buffer,
                                                                 Oid pg_class_oid, bool is_index);
 static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                                                                DumpableObject *dobj,
                                                                const char *objlabel);
 static const char *getAttrName(int attrnum, TableInfo *tblInfo);
-static const char *fmtCopyColumnList(const TableInfo *ti);
-static void do_sql_command(PGconn *conn, const char *query);
-static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
-                                ExecStatusType expected);
+static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer);
+static char *get_synchronized_snapshot(Archive *fout);
+static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
+static void setupDumpWorker(Archive *AHX, RestoreOptions *ropt);
+
 
 int
 main(int argc, char **argv)
@@ -262,13 +278,14 @@ main(int argc, char **argv)
        const char *pgport = NULL;
        const char *username = NULL;
        const char *dumpencoding = NULL;
-       const char *std_strings;
        bool            oids = false;
        TableInfo  *tblinfo;
        int                     numTables;
        DumpableObject **dobjs;
        int                     numObjs;
+       DumpableObject *boundaryObjs;
        int                     i;
+       int                     numWorkers = 1;
        enum trivalue prompt_password = TRI_DEFAULT;
        int                     compressLevel = -1;
        int                     plainText = 0;
@@ -278,11 +295,11 @@ main(int argc, char **argv)
        int                     outputNoOwner = 0;
        char       *outputSuperuser = NULL;
        char       *use_role = NULL;
-       int                     my_version;
        int                     optindex;
        RestoreOptions *ropt;
        ArchiveFormat archiveFormat = archUnknown;
        ArchiveMode archiveMode;
+       Archive    *fout;                       /* the script file */
 
        static int      disable_triggers = 0;
        static int      outputNoTablespaces = 0;
@@ -293,10 +310,12 @@ main(int argc, char **argv)
                {"blobs", no_argument, NULL, 'b'},
                {"clean", no_argument, NULL, 'c'},
                {"create", no_argument, NULL, 'C'},
+               {"dbname", required_argument, NULL, 'd'},
                {"file", required_argument, NULL, 'f'},
                {"format", required_argument, NULL, 'F'},
                {"host", required_argument, NULL, 'h'},
                {"ignore-version", no_argument, NULL, 'i'},
+               {"jobs", 1, NULL, 'j'},
                {"no-reconnect", no_argument, NULL, 'R'},
                {"oids", no_argument, NULL, 'o'},
                {"no-owner", no_argument, NULL, 'O'},
@@ -327,6 +346,7 @@ main(int argc, char **argv)
                {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
                {"disable-triggers", no_argument, &disable_triggers, 1},
                {"exclude-table-data", required_argument, NULL, 4},
+               {"if-exists", no_argument, &if_exists, 1},
                {"inserts", no_argument, &dump_inserts, 1},
                {"lock-wait-timeout", required_argument, NULL, 2},
                {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
@@ -336,6 +356,7 @@ main(int argc, char **argv)
                {"serializable-deferrable", no_argument, &serializable_deferrable, 1},
                {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
                {"no-security-labels", no_argument, &no_security_labels, 1},
+               {"no-synchronized-snapshots", no_argument, &no_synchronized_snapshots, 1},
                {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1},
 
                {NULL, 0, NULL, 0}
@@ -343,6 +364,12 @@ main(int argc, char **argv)
 
        set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
 
+       /*
+        * Initialize what we need for parallel execution, especially for thread
+        * support on Windows.
+        */
+       init_parallel_dump_utils();
+
        g_verbose = false;
 
        strcpy(g_comment_start, "-- ");
@@ -364,16 +391,16 @@ main(int argc, char **argv)
                if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
                {
                        help(progname);
-                       exit(0);
+                       exit_nicely(0);
                }
                if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
                {
                        puts("pg_dump (PostgreSQL) " PG_VERSION);
-                       exit(0);
+                       exit_nicely(0);
                }
        }
 
-       while ((c = getopt_long(argc, argv, "abcCE:f:F:h:in:N:oOp:RsS:t:T:U:vwWxZ:",
+       while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:ij:n:N:oOp:RsS:t:T:U:vwWxZ:",
                                                        long_options, &optindex)) != -1)
        {
                switch (c)
@@ -394,26 +421,34 @@ main(int argc, char **argv)
                                outputCreateDB = 1;
                                break;
 
+                       case 'd':                       /* database name */
+                               dbname = pg_strdup(optarg);
+                               break;
+
                        case 'E':                       /* Dump encoding */
-                               dumpencoding = optarg;
+                               dumpencoding = pg_strdup(optarg);
                                break;
 
                        case 'f':
-                               filename = optarg;
+                               filename = pg_strdup(optarg);
                                break;
 
                        case 'F':
-                               format = optarg;
+                               format = pg_strdup(optarg);
                                break;
 
                        case 'h':                       /* server host */
-                               pghost = optarg;
+                               pghost = pg_strdup(optarg);
                                break;
 
                        case 'i':
                                /* ignored, deprecated option */
                                break;
 
+                       case 'j':                       /* number of dump jobs */
+                               numWorkers = atoi(optarg);
+                               break;
+
                        case 'n':                       /* include schema(s) */
                                simple_string_list_append(&schema_include_patterns, optarg);
                                include_everything = false;
@@ -432,7 +467,7 @@ main(int argc, char **argv)
                                break;
 
                        case 'p':                       /* server port */
-                               pgport = optarg;
+                               pgport = pg_strdup(optarg);
                                break;
 
                        case 'R':
@@ -457,7 +492,7 @@ main(int argc, char **argv)
                                break;
 
                        case 'U':
-                               username = optarg;
+                               username = pg_strdup(optarg);
                                break;
 
                        case 'v':                       /* verbose */
@@ -485,29 +520,32 @@ main(int argc, char **argv)
                                break;
 
                        case 2:                         /* lock-wait-timeout */
-                               lockWaitTimeout = optarg;
+                               lockWaitTimeout = pg_strdup(optarg);
                                break;
 
                        case 3:                         /* SET ROLE */
-                               use_role = optarg;
+                               use_role = pg_strdup(optarg);
                                break;
 
-                       case 4:                 /* exclude table(s) data */
+                       case 4:                         /* exclude table(s) data */
                                simple_string_list_append(&tabledata_exclude_patterns, optarg);
                                break;
 
                        case 5:                         /* section */
-                               set_section(optarg, &dumpSections);
+                               set_dump_section(optarg, &dumpSections);
                                break;
 
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
-                               exit(1);
+                               exit_nicely(1);
                }
        }
 
-       /* Get database name from command line */
-       if (optind < argc)
+       /*
+        * Non-option argument specifies database name as long as it wasn't
+        * already specified with -d / --dbname
+        */
+       if (optind < argc && dbname == NULL)
                dbname = argv[optind++];
 
        /* Complain if any arguments remain */
@@ -517,7 +555,7 @@ main(int argc, char **argv)
                                progname, argv[optind]);
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                                progname);
-               exit(1);
+               exit_nicely(1);
        }
 
        /* --column-inserts implies --inserts */
@@ -527,38 +565,25 @@ main(int argc, char **argv)
        if (dataOnly && schemaOnly)
        {
                write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
-               exit(1);
-       }
-
-       if ((dataOnly || schemaOnly) && dumpSections != DUMP_UNSECTIONED)
-       {
-               write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used with --section\n");
-               exit(1);
-       }
-
-       if (dataOnly)
-               dumpSections = DUMP_DATA;
-       else if (schemaOnly)
-               dumpSections = DUMP_PRE_DATA | DUMP_POST_DATA;
-       else if ( dumpSections != DUMP_UNSECTIONED)
-       {
-               dataOnly = dumpSections == DUMP_DATA;
-               schemaOnly = !(dumpSections & DUMP_DATA);
+               exit_nicely(1);
        }
 
        if (dataOnly && outputClean)
        {
                write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
-               exit(1);
+               exit_nicely(1);
        }
 
        if (dump_inserts && oids)
        {
                write_msg(NULL, "options --inserts/--column-inserts and -o/--oids cannot be used together\n");
                write_msg(NULL, "(The INSERT command cannot set OIDs.)\n");
-               exit(1);
+               exit_nicely(1);
        }
 
+       if (if_exists && !outputClean)
+               exit_horribly(NULL, "option --if-exists requires -c/--clean option\n");
+
        /* Identify archive format to emit */
        archiveFormat = parseArchiveFormat(format, &archiveMode);
 
@@ -575,143 +600,101 @@ main(int argc, char **argv)
                        compressLevel = 0;
        }
 
-       /* Open the output file */
-       g_fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode);
-
-       if (g_fout == NULL)
-       {
-               write_msg(NULL, "could not open output file \"%s\" for writing\n", filename);
-               exit(1);
-       }
-
-       /* Let the archiver know how noisy to be */
-       g_fout->verbose = g_verbose;
-
-       my_version = parse_version(PG_VERSION);
-       if (my_version < 0)
-       {
-               write_msg(NULL, "could not parse version string \"%s\"\n", PG_VERSION);
-               exit(1);
-       }
-
-       /*
-        * We allow the server to be back to 7.0, and up to any minor release of
-        * our own major version.  (See also version check in pg_dumpall.c.)
-        */
-       g_fout->minRemoteVersion = 70000;
-       g_fout->maxRemoteVersion = (my_version / 100) * 100 + 99;
-
-       /*
-        * Open the database using the Archiver, so it knows about it. Errors mean
-        * death.
-        */
-       g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport,
-                                                        username, prompt_password);
-
-       /* Set the client encoding if requested */
-       if (dumpencoding)
-       {
-               if (PQsetClientEncoding(g_conn, dumpencoding) < 0)
-               {
-                       write_msg(NULL, "invalid client encoding \"%s\" specified\n",
-                                         dumpencoding);
-                       exit(1);
-               }
-       }
-
        /*
-        * Get the active encoding and the standard_conforming_strings setting, so
-        * we know how to escape strings.
+        * On Windows we can only have at most MAXIMUM_WAIT_OBJECTS (= 64 usually)
+        * parallel jobs because that's the maximum limit for the
+        * WaitForMultipleObjects() call.
         */
-       g_fout->encoding = PQclientEncoding(g_conn);
-
-       std_strings = PQparameterStatus(g_conn, "standard_conforming_strings");
-       g_fout->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
+       if (numWorkers <= 0
+#ifdef WIN32
+               || numWorkers > MAXIMUM_WAIT_OBJECTS
+#endif
+               )
+               exit_horribly(NULL, "%s: invalid number of parallel jobs\n", progname);
 
-       /* Set the role if requested */
-       if (use_role && g_fout->remoteVersion >= 80100)
-       {
-               PQExpBuffer query = createPQExpBuffer();
+       /* Parallel backup only in the directory archive format so far */
+       if (archiveFormat != archDirectory && numWorkers > 1)
+               exit_horribly(NULL, "parallel backup only supported by the directory format\n");
 
-               appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
-               do_sql_command(g_conn, query->data);
-               destroyPQExpBuffer(query);
-       }
+       /* Open the output file */
+       fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode,
+                                                setupDumpWorker);
 
-       /* Set the datestyle to ISO to ensure the dump's portability */
-       do_sql_command(g_conn, "SET DATESTYLE = ISO");
+       /* Register the cleanup hook */
+       on_exit_close_archive(fout);
 
-       /* Likewise, avoid using sql_standard intervalstyle */
-       if (g_fout->remoteVersion >= 80400)
-               do_sql_command(g_conn, "SET INTERVALSTYLE = POSTGRES");
+       if (fout == NULL)
+               exit_horribly(NULL, "could not open output file \"%s\" for writing\n", filename);
 
-       /*
-        * If supported, set extra_float_digits so that we can dump float data
-        * exactly (given correctly implemented float I/O code, anyway)
-        */
-       if (g_fout->remoteVersion >= 90000)
-               do_sql_command(g_conn, "SET extra_float_digits TO 3");
-       else if (g_fout->remoteVersion >= 70400)
-               do_sql_command(g_conn, "SET extra_float_digits TO 2");
+       /* Let the archiver know how noisy to be */
+       fout->verbose = g_verbose;
 
        /*
-        * If synchronized scanning is supported, disable it, to prevent
-        * unpredictable changes in row ordering across a dump and reload.
+        * We allow the server to be back to 7.0, and up to any minor release of
+        * our own major version.  (See also version check in pg_dumpall.c.)
         */
-       if (g_fout->remoteVersion >= 80300)
-               do_sql_command(g_conn, "SET synchronize_seqscans TO off");
+       fout->minRemoteVersion = 70000;
+       fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
 
-       /*
-        * Disable timeouts if supported.
-        */
-       if (g_fout->remoteVersion >= 70300)
-               do_sql_command(g_conn, "SET statement_timeout = 0");
+       fout->numWorkers = numWorkers;
 
        /*
-        * Quote all identifiers, if requested.
+        * Open the database using the Archiver, so it knows about it. Errors mean
+        * death.
         */
-       if (quote_all_identifiers && g_fout->remoteVersion >= 90100)
-               do_sql_command(g_conn, "SET quote_all_identifiers = true");
+       ConnectDatabase(fout, dbname, pghost, pgport, username, prompt_password);
+       setup_connection(fout, dumpencoding, use_role);
 
        /*
         * Disable security label support if server version < v9.1.x (prevents
         * access to nonexistent pg_seclabel catalog)
         */
-       if (g_fout->remoteVersion < 90100)
+       if (fout->remoteVersion < 90100)
                no_security_labels = 1;
 
        /*
-        * Start transaction-snapshot mode transaction to dump consistent data.
+        * When running against 9.0 or later, check if we are in recovery mode,
+        * which means we are on a hot standby.
         */
-       do_sql_command(g_conn, "BEGIN");
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90000)
        {
-               if (serializable_deferrable)
-                       do_sql_command(g_conn,
-                                                  "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, "
-                                                  "READ ONLY, DEFERRABLE");
-               else
-                       do_sql_command(g_conn,
-                                                  "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ");
+               PGresult   *res = ExecuteSqlQueryForSingleRow(fout, "SELECT pg_catalog.pg_is_in_recovery()");
+
+               if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
+               {
+                       /*
+                        * On hot standby slaves, never try to dump unlogged table data,
+                        * since it will just throw an error.
+                        */
+                       no_unlogged_table_data = true;
+               }
+               PQclear(res);
        }
-       else
-               do_sql_command(g_conn, "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
 
        /* Select the appropriate subquery to convert user IDs to names */
-       if (g_fout->remoteVersion >= 80100)
+       if (fout->remoteVersion >= 80100)
                username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
                username_subquery = "SELECT usename FROM pg_catalog.pg_user WHERE usesysid =";
        else
                username_subquery = "SELECT usename FROM pg_user WHERE usesysid =";
 
+       /* check the version for the synchronized snapshots feature */
+       if (numWorkers > 1 && fout->remoteVersion < 90200
+               && !no_synchronized_snapshots)
+               exit_horribly(NULL,
+                "Synchronized snapshots are not supported by this server version.\n"
+                 "Run with --no-synchronized-snapshots instead if you do not need\n"
+                                         "synchronized snapshots.\n");
+
        /* Find the last built-in OID, if needed */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
        {
-               if (g_fout->remoteVersion >= 70100)
-                       g_last_builtin_oid = findLastBuiltinOid_V71(PQdb(g_conn));
+               if (fout->remoteVersion >= 70100)
+                       g_last_builtin_oid = findLastBuiltinOid_V71(fout,
+                                                                                                 PQdb(GetConnection(fout)));
                else
-                       g_last_builtin_oid = findLastBuiltinOid_V70();
+                       g_last_builtin_oid = findLastBuiltinOid_V70(fout);
                if (g_verbose)
                        write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
        }
@@ -719,33 +702,27 @@ main(int argc, char **argv)
        /* Expand schema selection patterns into OID lists */
        if (schema_include_patterns.head != NULL)
        {
-               expand_schema_name_patterns(&schema_include_patterns,
+               expand_schema_name_patterns(fout, &schema_include_patterns,
                                                                        &schema_include_oids);
                if (schema_include_oids.head == NULL)
-               {
-                       write_msg(NULL, "No matching schemas were found\n");
-                       exit_nicely();
-               }
+                       exit_horribly(NULL, "No matching schemas were found\n");
        }
-       expand_schema_name_patterns(&schema_exclude_patterns,
+       expand_schema_name_patterns(fout, &schema_exclude_patterns,
                                                                &schema_exclude_oids);
        /* non-matching exclusion patterns aren't an error */
 
        /* Expand table selection patterns into OID lists */
        if (table_include_patterns.head != NULL)
        {
-               expand_table_name_patterns(&table_include_patterns,
+               expand_table_name_patterns(fout, &table_include_patterns,
                                                                   &table_include_oids);
                if (table_include_oids.head == NULL)
-               {
-                       write_msg(NULL, "No matching tables were found\n");
-                       exit_nicely();
-               }
+                       exit_horribly(NULL, "No matching tables were found\n");
        }
-       expand_table_name_patterns(&table_exclude_patterns,
+       expand_table_name_patterns(fout, &table_exclude_patterns,
                                                           &table_exclude_oids);
 
-       expand_table_name_patterns(&tabledata_exclude_patterns,
+       expand_table_name_patterns(fout, &tabledata_exclude_patterns,
                                                           &tabledata_exclude_oids);
 
        /* non-matching exclusion patterns aren't an error */
@@ -761,25 +738,37 @@ main(int argc, char **argv)
         * Now scan the database and create DumpableObject structs for all the
         * objects we intend to dump.
         */
-       tblinfo = getSchemaData(&numTables);
+       tblinfo = getSchemaData(fout, &numTables);
 
-       if (g_fout->remoteVersion < 80400)
+       if (fout->remoteVersion < 80400)
                guessConstraintInheritance(tblinfo, numTables);
 
        if (!schemaOnly)
        {
                getTableData(tblinfo, numTables, oids);
+               buildMatViewRefreshDependencies(fout);
                if (dataOnly)
                        getTableDataFKConstraints();
        }
 
        if (outputBlobs)
-               getBlobs(g_fout);
+               getBlobs(fout);
 
        /*
         * Collect dependency data to assist in ordering the objects.
         */
-       getDependencies();
+       getDependencies(fout);
+
+       /* Lastly, create dummy objects to represent the section boundaries */
+       boundaryObjs = createBoundaryObjects();
+
+       /* Get pointers to all the known DumpableObjects */
+       getDumpableObjects(&dobjs, &numObjs);
+
+       /*
+        * Add dummy dependencies to enforce the dump section ordering.
+        */
+       addBoundaryDependencies(dobjs, numObjs, boundaryObjs);
 
        /*
         * Sort the objects into a safe dump order (no forward references).
@@ -790,14 +779,17 @@ main(int argc, char **argv)
         * will dump identically.  Before 7.3 we don't have dependencies and we
         * use OID ordering as an (unreliable) guide to creation order.
         */
-       getDumpableObjects(&dobjs, &numObjs);
-
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
                sortDumpableObjectsByTypeName(dobjs, numObjs);
        else
                sortDumpableObjectsByTypeOid(dobjs, numObjs);
 
-       sortDumpableObjects(dobjs, numObjs);
+       /* If we do a parallel dump, we want the largest tables to go first */
+       if (archiveFormat == archDirectory && numWorkers > 1)
+               sortDataAndIndexObjectsBySize(dobjs, numObjs);
+
+       sortDumpableObjects(dobjs, numObjs,
+                                               boundaryObjs[0].dumpId, boundaryObjs[1].dumpId);
 
        /*
         * Create archive TOC entries for all the objects to be dumped, in a safe
@@ -805,49 +797,65 @@ main(int argc, char **argv)
         */
 
        /* First the special ENCODING and STDSTRINGS entries. */
-       dumpEncoding(g_fout);
-       dumpStdStrings(g_fout);
+       dumpEncoding(fout);
+       dumpStdStrings(fout);
 
        /* The database item is always next, unless we don't want it at all */
        if (include_everything && !dataOnly)
-               dumpDatabase(g_fout);
+               dumpDatabase(fout);
 
        /* Now the rearrangeable objects. */
        for (i = 0; i < numObjs; i++)
-               dumpDumpableObject(g_fout, dobjs[i]);
+               dumpDumpableObject(fout, dobjs[i]);
 
        /*
-        * And finally we can do the actual output.
+        * Set up options info to ensure we dump what we want.
         */
-       if (plainText)
-       {
-               ropt = NewRestoreOptions();
-               ropt->filename = (char *) filename;
-               ropt->dropSchema = outputClean;
-               ropt->aclsSkip = aclsSkip;
-               ropt->superuser = outputSuperuser;
-               ropt->createDB = outputCreateDB;
-               ropt->noOwner = outputNoOwner;
-               ropt->noTablespace = outputNoTablespaces;
-               ropt->disable_triggers = disable_triggers;
-               ropt->use_setsessauth = use_setsessauth;
-               ropt->dataOnly = dataOnly;
-
-               if (compressLevel == -1)
-                       ropt->compression = 0;
-               else
-                       ropt->compression = compressLevel;
+       ropt = NewRestoreOptions();
+       ropt->filename = filename;
+       ropt->dropSchema = outputClean;
+       ropt->dataOnly = dataOnly;
+       ropt->schemaOnly = schemaOnly;
+       ropt->if_exists = if_exists;
+       ropt->dumpSections = dumpSections;
+       ropt->aclsSkip = aclsSkip;
+       ropt->superuser = outputSuperuser;
+       ropt->createDB = outputCreateDB;
+       ropt->noOwner = outputNoOwner;
+       ropt->noTablespace = outputNoTablespaces;
+       ropt->disable_triggers = disable_triggers;
+       ropt->use_setsessauth = use_setsessauth;
 
-               ropt->suppressDumpWarnings = true;              /* We've already shown them */
+       if (compressLevel == -1)
+               ropt->compression = 0;
+       else
+               ropt->compression = compressLevel;
 
-               RestoreArchive(g_fout, ropt);
-       }
+       ropt->suppressDumpWarnings = true;      /* We've already shown them */
+
+       SetArchiveRestoreOptions(fout, ropt);
 
-       CloseArchive(g_fout);
+       /*
+        * The archive's TOC entries are now marked as to which ones will actually
+        * be output, so we can set up their dependency lists properly. This isn't
+        * necessary for plain-text output, though.
+        */
+       if (!plainText)
+               BuildArchiveDependencies(fout);
+
+       /*
+        * And finally we can do the actual output.
+        *
+        * Note: for non-plain-text output formats, the output file is written
+        * inside CloseArchive().  This is, um, bizarre; but not worth changing
+        * right now.
+        */
+       if (plainText)
+               RestoreArchive(fout);
 
-       PQfinish(g_conn);
+       CloseArchive(fout);
 
-       exit(0);
+       exit_nicely(0);
 }
 
 
@@ -859,48 +867,52 @@ help(const char *progname)
        printf(_("  %s [OPTION]... [DBNAME]\n"), progname);
 
        printf(_("\nGeneral options:\n"));
-       printf(_("  -f, --file=FILENAME         output file or directory name\n"));
-       printf(_("  -F, --format=c|d|t|p        output file format (custom, directory, tar,\n"
-                        "                              plain text (default))\n"));
-       printf(_("  -v, --verbose               verbose mode\n"));
-       printf(_("  -Z, --compress=0-9          compression level for compressed formats\n"));
-       printf(_("  --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
-       printf(_("  --help                      show this help, then exit\n"));
-       printf(_("  --version                   output version information, then exit\n"));
+       printf(_("  -f, --file=FILENAME          output file or directory name\n"));
+       printf(_("  -F, --format=c|d|t|p         output file format (custom, directory, tar,\n"
+                        "                               plain text (default))\n"));
+       printf(_("  -j, --jobs=NUM               use this many parallel jobs to dump\n"));
+       printf(_("  -v, --verbose                verbose mode\n"));
+       printf(_("  -V, --version                output version information, then exit\n"));
+       printf(_("  -Z, --compress=0-9           compression level for compressed formats\n"));
+       printf(_("  --lock-wait-timeout=TIMEOUT  fail after waiting TIMEOUT for a table lock\n"));
+       printf(_("  -?, --help                   show this help, then exit\n"));
 
        printf(_("\nOptions controlling the output content:\n"));
-       printf(_("  -a, --data-only             dump only the data, not the schema\n"));
-       printf(_("  -b, --blobs                 include large objects in dump\n"));
-       printf(_("  -c, --clean                 clean (drop) database objects before recreating\n"));
-       printf(_("  -C, --create                include commands to create database in dump\n"));
-       printf(_("  -E, --encoding=ENCODING     dump the data in encoding ENCODING\n"));
-       printf(_("  -n, --schema=SCHEMA         dump the named schema(s) only\n"));
-       printf(_("  -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n"));
-       printf(_("  -o, --oids                  include OIDs in dump\n"));
-       printf(_("  -O, --no-owner              skip restoration of object ownership in\n"
-                        "                              plain-text format\n"));
-       printf(_("  -s, --schema-only           dump only the schema, no data\n"));
-       printf(_("  -S, --superuser=NAME        superuser user name to use in plain-text format\n"));
-       printf(_("  -t, --table=TABLE           dump the named table(s) only\n"));
-       printf(_("  -T, --exclude-table=TABLE   do NOT dump the named table(s)\n"));
-       printf(_("  -x, --no-privileges         do not dump privileges (grant/revoke)\n"));
-       printf(_("  --binary-upgrade            for use by upgrade utilities only\n"));
-       printf(_("  --column-inserts            dump data as INSERT commands with column names\n"));
-       printf(_("  --disable-dollar-quoting    disable dollar quoting, use SQL standard quoting\n"));
-       printf(_("  --disable-triggers          disable triggers during data-only restore\n"));
-       printf(_("  --exclude-table-data=TABLE  do NOT dump data for the named table(s)\n"));
-       printf(_("  --inserts                   dump data as INSERT commands, rather than COPY\n"));
-       printf(_("  --no-security-labels        do not dump security label assignments\n"));
-       printf(_("  --no-tablespaces            do not dump tablespace assignments\n"));
-       printf(_("  --no-unlogged-table-data    do not dump unlogged table data\n"));
-       printf(_("  --quote-all-identifiers     quote all identifiers, even if not key words\n"));
-       printf(_("  --section=SECTION           dump named section (pre-data, data or post-data)\n"));
-       printf(_("  --serializable-deferrable   wait until the dump can run without anomalies\n"));
+       printf(_("  -a, --data-only              dump only the data, not the schema\n"));
+       printf(_("  -b, --blobs                  include large objects in dump\n"));
+       printf(_("  -c, --clean                  clean (drop) database objects before recreating\n"));
+       printf(_("  -C, --create                 include commands to create database in dump\n"));
+       printf(_("  -E, --encoding=ENCODING      dump the data in encoding ENCODING\n"));
+       printf(_("  -n, --schema=SCHEMA          dump the named schema(s) only\n"));
+       printf(_("  -N, --exclude-schema=SCHEMA  do NOT dump the named schema(s)\n"));
+       printf(_("  -o, --oids                   include OIDs in dump\n"));
+       printf(_("  -O, --no-owner               skip restoration of object ownership in\n"
+                        "                               plain-text format\n"));
+       printf(_("  -s, --schema-only            dump only the schema, no data\n"));
+       printf(_("  -S, --superuser=NAME         superuser user name to use in plain-text format\n"));
+       printf(_("  -t, --table=TABLE            dump the named table(s) only\n"));
+       printf(_("  -T, --exclude-table=TABLE    do NOT dump the named table(s)\n"));
+       printf(_("  -x, --no-privileges          do not dump privileges (grant/revoke)\n"));
+       printf(_("  --binary-upgrade             for use by upgrade utilities only\n"));
+       printf(_("  --column-inserts             dump data as INSERT commands with column names\n"));
+       printf(_("  --disable-dollar-quoting     disable dollar quoting, use SQL standard quoting\n"));
+       printf(_("  --disable-triggers           disable triggers during data-only restore\n"));
+       printf(_("  --exclude-table-data=TABLE   do NOT dump data for the named table(s)\n"));
+       printf(_("  --if-exists                  use IF EXISTS when dropping objects\n"));
+       printf(_("  --inserts                    dump data as INSERT commands, rather than COPY\n"));
+       printf(_("  --no-security-labels         do not dump security label assignments\n"));
+       printf(_("  --no-synchronized-snapshots  do not use synchronized snapshots in parallel jobs\n"));
+       printf(_("  --no-tablespaces             do not dump tablespace assignments\n"));
+       printf(_("  --no-unlogged-table-data     do not dump unlogged table data\n"));
+       printf(_("  --quote-all-identifiers      quote all identifiers, even if not key words\n"));
+       printf(_("  --section=SECTION            dump named section (pre-data, data, or post-data)\n"));
+       printf(_("  --serializable-deferrable    wait until the dump can run without anomalies\n"));
        printf(_("  --use-set-session-authorization\n"
-                        "                              use SET SESSION AUTHORIZATION commands instead of\n"
-       "                              ALTER OWNER commands to set ownership\n"));
+                        "                               use SET SESSION AUTHORIZATION commands instead of\n"
+                        "                               ALTER OWNER commands to set ownership\n"));
 
        printf(_("\nConnection options:\n"));
+       printf(_("  -d, --dbname=DBNAME      database to dump\n"));
        printf(_("  -h, --host=HOSTNAME      database server host or socket directory\n"));
        printf(_("  -p, --port=PORT          database server port number\n"));
        printf(_("  -U, --username=NAME      connect as specified database user\n"));
@@ -913,13 +925,151 @@ help(const char *progname)
        printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
 }
 
-void
-exit_nicely(void)
+static void
+setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
 {
-       PQfinish(g_conn);
-       if (g_verbose)
-               write_msg(NULL, "*** aborted because of error\n");
-       exit(1);
+       PGconn     *conn = GetConnection(AH);
+       const char *std_strings;
+
+       /*
+        * Set the client encoding if requested. If dumpencoding == NULL then
+        * either it hasn't been requested or we're a cloned connection and then
+        * this has already been set in CloneArchive according to the original
+        * connection encoding.
+        */
+       if (dumpencoding)
+       {
+               if (PQsetClientEncoding(conn, dumpencoding) < 0)
+                       exit_horribly(NULL, "invalid client encoding \"%s\" specified\n",
+                                                 dumpencoding);
+       }
+
+       /*
+        * Get the active encoding and the standard_conforming_strings setting, so
+        * we know how to escape strings.
+        */
+       AH->encoding = PQclientEncoding(conn);
+
+       std_strings = PQparameterStatus(conn, "standard_conforming_strings");
+       AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
+
+       /* Set the role if requested */
+       if (!use_role && AH->use_role)
+               use_role = AH->use_role;
+
+       /* Set the role if requested */
+       if (use_role && AH->remoteVersion >= 80100)
+       {
+               PQExpBuffer query = createPQExpBuffer();
+
+               appendPQExpBuffer(query, "SET ROLE %s", fmtId(use_role));
+               ExecuteSqlStatement(AH, query->data);
+               destroyPQExpBuffer(query);
+
+               /* save this for later use on parallel connections */
+               if (!AH->use_role)
+                       AH->use_role = strdup(use_role);
+       }
+
+       /* Set the datestyle to ISO to ensure the dump's portability */
+       ExecuteSqlStatement(AH, "SET DATESTYLE = ISO");
+
+       /* Likewise, avoid using sql_standard intervalstyle */
+       if (AH->remoteVersion >= 80400)
+               ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES");
+
+       /*
+        * If supported, set extra_float_digits so that we can dump float data
+        * exactly (given correctly implemented float I/O code, anyway)
+        */
+       if (AH->remoteVersion >= 90000)
+               ExecuteSqlStatement(AH, "SET extra_float_digits TO 3");
+       else if (AH->remoteVersion >= 70400)
+               ExecuteSqlStatement(AH, "SET extra_float_digits TO 2");
+
+       /*
+        * If synchronized scanning is supported, disable it, to prevent
+        * unpredictable changes in row ordering across a dump and reload.
+        */
+       if (AH->remoteVersion >= 80300)
+               ExecuteSqlStatement(AH, "SET synchronize_seqscans TO off");
+
+       /*
+        * Disable timeouts if supported.
+        */
+       if (AH->remoteVersion >= 70300)
+               ExecuteSqlStatement(AH, "SET statement_timeout = 0");
+       if (AH->remoteVersion >= 90300)
+               ExecuteSqlStatement(AH, "SET lock_timeout = 0");
+
+       /*
+        * Quote all identifiers, if requested.
+        */
+       if (quote_all_identifiers && AH->remoteVersion >= 90100)
+               ExecuteSqlStatement(AH, "SET quote_all_identifiers = true");
+
+       /*
+        * Start transaction-snapshot mode transaction to dump consistent data.
+        */
+       ExecuteSqlStatement(AH, "BEGIN");
+       if (AH->remoteVersion >= 90100)
+       {
+               if (serializable_deferrable)
+                       ExecuteSqlStatement(AH,
+                                                               "SET TRANSACTION ISOLATION LEVEL "
+                                                               "SERIALIZABLE, READ ONLY, DEFERRABLE");
+               else
+                       ExecuteSqlStatement(AH,
+                                                               "SET TRANSACTION ISOLATION LEVEL "
+                                                               "REPEATABLE READ, READ ONLY");
+       }
+       else if (AH->remoteVersion >= 70400)
+       {
+               /* note: comma was not accepted in SET TRANSACTION before 8.0 */
+               ExecuteSqlStatement(AH,
+                                                       "SET TRANSACTION ISOLATION LEVEL "
+                                                       "SERIALIZABLE READ ONLY");
+       }
+       else
+               ExecuteSqlStatement(AH,
+                                                       "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
+
+
+
+       if (AH->numWorkers > 1 && AH->remoteVersion >= 90200 && !no_synchronized_snapshots)
+       {
+               if (AH->sync_snapshot_id)
+               {
+                       PQExpBuffer query = createPQExpBuffer();
+
+                       appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT ");
+                       appendStringLiteralConn(query, AH->sync_snapshot_id, conn);
+                       ExecuteSqlStatement(AH, query->data);
+                       destroyPQExpBuffer(query);
+               }
+               else
+                       AH->sync_snapshot_id = get_synchronized_snapshot(AH);
+       }
+}
+
+static void
+setupDumpWorker(Archive *AHX, RestoreOptions *ropt)
+{
+       setup_connection(AHX, NULL, NULL);
+}
+
+static char *
+get_synchronized_snapshot(Archive *fout)
+{
+       char       *query = "SELECT pg_export_snapshot()";
+       char       *result;
+       PGresult   *res;
+
+       res = ExecuteSqlQueryForSingleRow(fout, query);
+       result = strdup(PQgetvalue(res, 0, 0));
+       PQclear(res);
+
+       return result;
 }
 
 static ArchiveFormat
@@ -943,13 +1093,6 @@ parseArchiveFormat(const char *format, ArchiveMode *mode)
                archiveFormat = archDirectory;
        else if (pg_strcasecmp(format, "directory") == 0)
                archiveFormat = archDirectory;
-       else if (pg_strcasecmp(format, "f") == 0 || pg_strcasecmp(format, "file") == 0)
-
-               /*
-                * Dump files into the current directory; for demonstration only, not
-                * documented.
-                */
-               archiveFormat = archFiles;
        else if (pg_strcasecmp(format, "p") == 0)
                archiveFormat = archNull;
        else if (pg_strcasecmp(format, "plain") == 0)
@@ -959,10 +1102,7 @@ parseArchiveFormat(const char *format, ArchiveMode *mode)
        else if (pg_strcasecmp(format, "tar") == 0)
                archiveFormat = archTar;
        else
-       {
-               write_msg(NULL, "invalid output format \"%s\" specified\n", format);
-               exit(1);
-       }
+               exit_horribly(NULL, "invalid output format \"%s\" specified\n", format);
        return archiveFormat;
 }
 
@@ -971,7 +1111,9 @@ parseArchiveFormat(const char *format, ArchiveMode *mode)
  * and append them to the given OID list.
  */
 static void
-expand_schema_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
+expand_schema_name_patterns(Archive *fout,
+                                                       SimpleStringList *patterns,
+                                                       SimpleOidList *oids)
 {
        PQExpBuffer query;
        PGresult   *res;
@@ -981,11 +1123,8 @@ expand_schema_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
        if (patterns->head == NULL)
                return;                                 /* nothing to do */
 
-       if (g_fout->remoteVersion < 70300)
-       {
-               write_msg(NULL, "server version must be at least 7.3 to use schema selection switches\n");
-               exit_nicely();
-       }
+       if (fout->remoteVersion < 70300)
+               exit_horribly(NULL, "server version must be at least 7.3 to use schema selection switches\n");
 
        query = createPQExpBuffer();
 
@@ -997,16 +1136,14 @@ expand_schema_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
        for (cell = patterns->head; cell; cell = cell->next)
        {
                if (cell != patterns->head)
-                       appendPQExpBuffer(query, "UNION ALL\n");
+                       appendPQExpBufferStr(query, "UNION ALL\n");
                appendPQExpBuffer(query,
                                                  "SELECT oid FROM pg_catalog.pg_namespace n\n");
-               processSQLNamePattern(g_conn, query, cell->val, false, false,
-                                                         NULL, "n.nspname", NULL,
-                                                         NULL);
+               processSQLNamePattern(GetConnection(fout), query, cell->val, false,
+                                                         false, NULL, "n.nspname", NULL, NULL);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        for (i = 0; i < PQntuples(res); i++)
        {
@@ -1022,7 +1159,8 @@ expand_schema_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
  * and append them to the given OID list.
  */
 static void
-expand_table_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
+expand_table_name_patterns(Archive *fout,
+                                                  SimpleStringList *patterns, SimpleOidList *oids)
 {
        PQExpBuffer query;
        PGresult   *res;
@@ -1042,21 +1180,20 @@ expand_table_name_patterns(SimpleStringList *patterns, SimpleOidList *oids)
        for (cell = patterns->head; cell; cell = cell->next)
        {
                if (cell != patterns->head)
-                       appendPQExpBuffer(query, "UNION ALL\n");
+                       appendPQExpBufferStr(query, "UNION ALL\n");
                appendPQExpBuffer(query,
                                                  "SELECT c.oid"
                                                  "\nFROM pg_catalog.pg_class c"
                "\n     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"
-                                                 "\nWHERE c.relkind in ('%c', '%c', '%c', '%c')\n",
+                                        "\nWHERE c.relkind in ('%c', '%c', '%c', '%c', '%c')\n",
                                                  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
-                                                 RELKIND_FOREIGN_TABLE);
-               processSQLNamePattern(g_conn, query, cell->val, true, false,
-                                                         "n.nspname", "c.relname", NULL,
+                                                 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
+               processSQLNamePattern(GetConnection(fout), query, cell->val, true,
+                                                         false, "n.nspname", "c.relname", NULL,
                                                          "pg_catalog.pg_table_is_visible(c.oid)");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        for (i = 0; i < PQntuples(res); i++)
        {
@@ -1123,15 +1260,6 @@ selectDumpableTable(TableInfo *tbinfo)
                simple_oid_list_member(&table_exclude_oids,
                                                           tbinfo->dobj.catId.oid))
                tbinfo->dobj.dump = false;
-
-       /* If table is to be dumped, check that the data is not excluded */
-       if (tbinfo->dobj.dump && !
-               simple_oid_list_member(&tabledata_exclude_oids,
-                                                          tbinfo->dobj.catId.oid))
-               tbinfo->dobj.dumpdata = true;
-       else
-               tbinfo->dobj.dumpdata = false;
-
 }
 
 /*
@@ -1168,6 +1296,7 @@ selectDumpableType(TypeInfo *tyinfo)
        if (tyinfo->isArray)
        {
                tyinfo->dobj.objType = DO_DUMMY_TYPE;
+
                /*
                 * Fall through to set the dump flag; we assume that the subsequent
                 * rules will do the same thing as they would for the array's base
@@ -1258,6 +1387,13 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        const bool      hasoids = tbinfo->hasoids;
        const bool      oids = tdinfo->oids;
        PQExpBuffer q = createPQExpBuffer();
+
+       /*
+        * Note: can't use getThreadLocalPQExpBuffer() here, we're calling fmtId
+        * which uses it already.
+        */
+       PQExpBuffer clistBuf = createPQExpBuffer();
+       PGconn     *conn = GetConnection(fout);
        PGresult   *res;
        int                     ret;
        char       *copybuf;
@@ -1272,7 +1408,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
         * this ensures reproducible results in case the table contains regproc,
         * regclass, etc columns.
         */
-       selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
        /*
         * If possible, specify the column list explicitly so that we have no
@@ -1280,15 +1416,16 @@ dumpTableData_copy(Archive *fout, void *dcontext)
         * column ordering of COPY will not be what we want in certain corner
         * cases involving ADD COLUMN and inheritance.)
         */
-       if (g_fout->remoteVersion >= 70300)
-               column_list = fmtCopyColumnList(tbinfo);
+       if (fout->remoteVersion >= 70300)
+               column_list = fmtCopyColumnList(tbinfo, clistBuf);
        else
                column_list = "";               /* can't select columns in COPY */
 
        if (oids && hasoids)
        {
                appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
-                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                 fmtQualifiedId(fout->remoteVersion,
+                                                                                tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  column_list);
        }
@@ -1305,24 +1442,26 @@ dumpTableData_copy(Archive *fout, void *dcontext)
                else
                        appendPQExpBufferStr(q, "* ");
                appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
-                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                 fmtQualifiedId(fout->remoteVersion,
+                                                                                tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  tdinfo->filtercond);
        }
        else
        {
                appendPQExpBuffer(q, "COPY %s %s TO stdout;",
-                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                 fmtQualifiedId(fout->remoteVersion,
+                                                                                tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  column_list);
        }
-       res = PQexec(g_conn, q->data);
-       check_sql_result(res, g_conn, q->data, PGRES_COPY_OUT);
+       res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
        PQclear(res);
+       destroyPQExpBuffer(clistBuf);
 
        for (;;)
        {
-               ret = PQgetCopyData(g_conn, &copybuf, 0);
+               ret = PQgetCopyData(conn, &copybuf, 0);
 
                if (ret < 0)
                        break;                          /* done or error */
@@ -1385,20 +1524,34 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        {
                /* copy data transfer failed */
                write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname);
-               write_msg(NULL, "Error message from server: %s", PQerrorMessage(g_conn));
+               write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
                write_msg(NULL, "The command was: %s\n", q->data);
-               exit_nicely();
+               exit_nicely(1);
        }
 
        /* Check command status and return to normal libpq state */
-       res = PQgetResult(g_conn);
-       check_sql_result(res, g_conn, q->data, PGRES_COMMAND_OK);
+       res = PQgetResult(conn);
+       if (PQresultStatus(res) != PGRES_COMMAND_OK)
+       {
+               write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname);
+               write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn));
+               write_msg(NULL, "The command was: %s\n", q->data);
+               exit_nicely(1);
+       }
        PQclear(res);
 
        destroyPQExpBuffer(q);
        return 1;
 }
 
+/*
+ * Dump table data using INSERT commands.
+ *
+ * Caution: when we restore from an archive file direct to database, the
+ * INSERT commands emitted by this function have to be parsed by
+ * pg_backup_db.c's ExecuteInsertCommands(), which will not handle comments,
+ * E'' strings, or dollar-quoted strings.  So don't emit anything like that.
+ */
 static int
 dumpTableData_insert(Archive *fout, void *dcontext)
 {
@@ -1406,6 +1559,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
        TableInfo  *tbinfo = tdinfo->tdtable;
        const char *classname = tbinfo->dobj.name;
        PQExpBuffer q = createPQExpBuffer();
+       PQExpBuffer insertStmt = NULL;
        PGresult   *res;
        int                     tuple;
        int                     nfields;
@@ -1417,66 +1571,87 @@ dumpTableData_insert(Archive *fout, void *dcontext)
         * this ensures reproducible results in case the table contains regproc,
         * regclass, etc columns.
         */
-       selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
        if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM ONLY %s",
-                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                 fmtQualifiedId(fout->remoteVersion,
+                                                                                tbinfo->dobj.namespace->dobj.name,
                                                                                 classname));
        }
        else
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM %s",
-                                                 fmtQualifiedId(tbinfo->dobj.namespace->dobj.name,
+                                                 fmtQualifiedId(fout->remoteVersion,
+                                                                                tbinfo->dobj.namespace->dobj.name,
                                                                                 classname));
        }
        if (tdinfo->filtercond)
                appendPQExpBuffer(q, " %s", tdinfo->filtercond);
 
-       res = PQexec(g_conn, q->data);
-       check_sql_result(res, g_conn, q->data, PGRES_COMMAND_OK);
+       ExecuteSqlStatement(fout, q->data);
 
-       do
+       while (1)
        {
-               PQclear(res);
-
-               res = PQexec(g_conn, "FETCH 100 FROM _pg_dump_cursor");
-               check_sql_result(res, g_conn, "FETCH 100 FROM _pg_dump_cursor",
-                                                PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor",
+                                                         PGRES_TUPLES_OK);
                nfields = PQnfields(res);
                for (tuple = 0; tuple < PQntuples(res); tuple++)
                {
-                       archprintf(fout, "INSERT INTO %s ", fmtId(classname));
-                       if (nfields == 0)
+                       /*
+                        * First time through, we build as much of the INSERT statement as
+                        * possible in "insertStmt", which we can then just print for each
+                        * line. If the table happens to have zero columns then this will
+                        * be a complete statement, otherwise it will end in "VALUES(" and
+                        * be ready to have the row's column values appended.
+                        */
+                       if (insertStmt == NULL)
                        {
+                               insertStmt = createPQExpBuffer();
+                               appendPQExpBuffer(insertStmt, "INSERT INTO %s ",
+                                                                 fmtId(classname));
+
                                /* corner case for zero-column table */
-                               archprintf(fout, "DEFAULT VALUES;\n");
-                               continue;
-                       }
-                       if (column_inserts)
-                       {
-                               resetPQExpBuffer(q);
-                               appendPQExpBuffer(q, "(");
-                               for (field = 0; field < nfields; field++)
+                               if (nfields == 0)
+                               {
+                                       appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
+                               }
+                               else
                                {
-                                       if (field > 0)
-                                               appendPQExpBuffer(q, ", ");
-                                       appendPQExpBufferStr(q, fmtId(PQfname(res, field)));
+                                       /* append the list of column names if required */
+                                       if (column_inserts)
+                                       {
+                                               appendPQExpBufferStr(insertStmt, "(");
+                                               for (field = 0; field < nfields; field++)
+                                               {
+                                                       if (field > 0)
+                                                               appendPQExpBufferStr(insertStmt, ", ");
+                                                       appendPQExpBufferStr(insertStmt,
+                                                                                                fmtId(PQfname(res, field)));
+                                               }
+                                               appendPQExpBufferStr(insertStmt, ") ");
+                                       }
+
+                                       appendPQExpBufferStr(insertStmt, "VALUES (");
                                }
-                               appendPQExpBuffer(q, ") ");
-                               archputs(q->data, fout);
                        }
-                       archprintf(fout, "VALUES (");
+
+                       archputs(insertStmt->data, fout);
+
+                       /* if it is zero-column table then we're done */
+                       if (nfields == 0)
+                               continue;
+
                        for (field = 0; field < nfields; field++)
                        {
                                if (field > 0)
-                                       archprintf(fout, ", ");
+                                       archputs(", ", fout);
                                if (PQgetisnull(res, tuple, field))
                                {
-                                       archprintf(fout, "NULL");
+                                       archputs("NULL", fout);
                                        continue;
                                }
 
@@ -1505,7 +1680,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                                        const char *s = PQgetvalue(res, tuple, field);
 
                                                        if (strspn(s, "0123456789 +-eE.") == strlen(s))
-                                                               archprintf(fout, "%s", s);
+                                                               archputs(s, fout);
                                                        else
                                                                archprintf(fout, "'%s'", s);
                                                }
@@ -1519,9 +1694,9 @@ dumpTableData_insert(Archive *fout, void *dcontext)
 
                                        case BOOLOID:
                                                if (strcmp(PQgetvalue(res, tuple, field), "t") == 0)
-                                                       archprintf(fout, "true");
+                                                       archputs("true", fout);
                                                else
-                                                       archprintf(fout, "false");
+                                                       archputs("false", fout);
                                                break;
 
                                        default:
@@ -1534,17 +1709,25 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                                break;
                                }
                        }
-                       archprintf(fout, ");\n");
+                       archputs(");\n", fout);
                }
-       } while (PQntuples(res) > 0);
-
-       PQclear(res);
-
-       archprintf(fout, "\n\n");
 
-       do_sql_command(g_conn, "CLOSE _pg_dump_cursor");
-
-       destroyPQExpBuffer(q);
+               if (PQntuples(res) <= 0)
+               {
+                       PQclear(res);
+                       break;
+               }
+               PQclear(res);
+       }
+
+       archputs("\n\n", fout);
+
+       ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
+
+       destroyPQExpBuffer(q);
+       if (insertStmt != NULL)
+               destroyPQExpBuffer(insertStmt);
+
        return 1;
 }
 
@@ -1560,13 +1743,10 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
 {
        TableInfo  *tbinfo = tdinfo->tdtable;
        PQExpBuffer copyBuf = createPQExpBuffer();
+       PQExpBuffer clistBuf = createPQExpBuffer();
        DataDumperPtr dumpFn;
        char       *copyStmt;
 
-       /* don't do anything if the data isn't wanted */
-       if (!tbinfo->dobj.dumpdata)
-               return;
-
        if (!dump_inserts)
        {
                /* Dump/restore using COPY */
@@ -1575,7 +1755,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                appendPQExpBuffer(copyBuf, "COPY %s ",
                                                  fmtId(tbinfo->dobj.name));
                appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
-                                                 fmtCopyColumnList(tbinfo),
+                                                 fmtCopyColumnList(tbinfo, clistBuf),
                                          (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
                copyStmt = copyBuf->data;
        }
@@ -1586,15 +1766,64 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                copyStmt = NULL;
        }
 
+       /*
+        * Note: although the TableDataInfo is a full DumpableObject, we treat its
+        * dependency on its table as "special" and pass it to ArchiveEntry now.
+        * See comments for BuildArchiveDependencies.
+        */
        ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
                                 tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name,
                                 NULL, tbinfo->rolname,
                                 false, "TABLE DATA", SECTION_DATA,
                                 "", "", copyStmt,
-                                tdinfo->dobj.dependencies, tdinfo->dobj.nDeps,
+                                &(tbinfo->dobj.dumpId), 1,
                                 dumpFn, tdinfo);
 
        destroyPQExpBuffer(copyBuf);
+       destroyPQExpBuffer(clistBuf);
+}
+
+/*
+ * refreshMatViewData -
+ *       load or refresh the contents of a single materialized view
+ *
+ * Actually, this just makes an ArchiveEntry for the REFRESH MATERIALIZED VIEW
+ * statement.
+ */
+static void
+refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
+{
+       TableInfo  *tbinfo = tdinfo->tdtable;
+       PQExpBuffer q;
+
+       /* If the materialized view is not flagged as populated, skip this. */
+       if (!tbinfo->relispopulated)
+               return;
+
+       q = createPQExpBuffer();
+
+       appendPQExpBuffer(q, "REFRESH MATERIALIZED VIEW %s;\n",
+                                         fmtId(tbinfo->dobj.name));
+
+       ArchiveEntry(fout,
+                                tdinfo->dobj.catId,    /* catalog ID */
+                                tdinfo->dobj.dumpId,   /* dump ID */
+                                tbinfo->dobj.name,             /* Name */
+                                tbinfo->dobj.namespace->dobj.name,             /* Namespace */
+                                NULL,                  /* Tablespace */
+                                tbinfo->rolname,               /* Owner */
+                                false,                 /* with oids */
+                                "MATERIALIZED VIEW DATA",              /* Desc */
+                                SECTION_POST_DATA,             /* Section */
+                                q->data,               /* Create */
+                                "",                    /* Del */
+                                NULL,                  /* Copy */
+                                tdinfo->dobj.dependencies,             /* Deps */
+                                tdinfo->dobj.nDeps,    /* # Deps */
+                                NULL,                  /* Dumper */
+                                NULL);                 /* Dumper Arg */
+
+       destroyPQExpBuffer(q);
 }
 
 /*
@@ -1608,36 +1837,53 @@ getTableData(TableInfo *tblinfo, int numTables, bool oids)
 
        for (i = 0; i < numTables; i++)
        {
-               /* Skip VIEWs (no data to dump) */
-               if (tblinfo[i].relkind == RELKIND_VIEW)
-                       continue;
-               /* Skip SEQUENCEs (handled elsewhere) */
-               if (tblinfo[i].relkind == RELKIND_SEQUENCE)
-                       continue;
-               /* Skip FOREIGN TABLEs (no data to dump) */
-               if (tblinfo[i].relkind == RELKIND_FOREIGN_TABLE)
-                       continue;
-               /* Skip unlogged tables if so requested */
-               if (tblinfo[i].relpersistence == RELPERSISTENCE_UNLOGGED
-                       && no_unlogged_table_data)
-                       continue;
-
-               if (tblinfo[i].dobj.dump && tblinfo[i].dataObj == NULL)
+               if (tblinfo[i].dobj.dump)
                        makeTableDataInfo(&(tblinfo[i]), oids);
        }
 }
 
 /*
  * Make a dumpable object for the data of this specific table
+ *
+ * Note: we make a TableDataInfo if and only if we are going to dump the
+ * table data; the "dump" flag in such objects isn't used.
  */
 static void
 makeTableDataInfo(TableInfo *tbinfo, bool oids)
 {
        TableDataInfo *tdinfo;
 
+       /*
+        * Nothing to do if we already decided to dump the table.  This will
+        * happen for "config" tables.
+        */
+       if (tbinfo->dataObj != NULL)
+               return;
+
+       /* Skip VIEWs (no data to dump) */
+       if (tbinfo->relkind == RELKIND_VIEW)
+               return;
+       /* Skip FOREIGN TABLEs (no data to dump) */
+       if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
+               return;
+
+       /* Don't dump data in unlogged tables, if so requested */
+       if (tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED &&
+               no_unlogged_table_data)
+               return;
+
+       /* Check that the data is not explicitly excluded */
+       if (simple_oid_list_member(&tabledata_exclude_oids,
+                                                          tbinfo->dobj.catId.oid))
+               return;
+
+       /* OK, let's dump it */
        tdinfo = (TableDataInfo *) pg_malloc(sizeof(TableDataInfo));
 
-       tdinfo->dobj.objType = DO_TABLE_DATA;
+       if (tbinfo->relkind == RELKIND_MATVIEW)
+               tdinfo->dobj.objType = DO_REFRESH_MATVIEW;
+       else
+               tdinfo->dobj.objType = DO_TABLE_DATA;
 
        /*
         * Note: use tableoid 0 so that this object won't be mistaken for
@@ -1656,6 +1902,117 @@ makeTableDataInfo(TableInfo *tbinfo, bool oids)
        tbinfo->dataObj = tdinfo;
 }
 
+/*
+ * The refresh for a materialized view must be dependent on the refresh for
+ * any materialized view that this one is dependent on.
+ *
+ * This must be called after all the objects are created, but before they are
+ * sorted.
+ */
+static void
+buildMatViewRefreshDependencies(Archive *fout)
+{
+       PQExpBuffer query;
+       PGresult   *res;
+       int                     ntups,
+                               i;
+       int                     i_classid,
+                               i_objid,
+                               i_refobjid;
+
+       /* No Mat Views before 9.3. */
+       if (fout->remoteVersion < 90300)
+               return;
+
+       /* Make sure we are in proper schema */
+       selectSourceSchema(fout, "pg_catalog");
+
+       query = createPQExpBuffer();
+
+       appendPQExpBufferStr(query, "WITH RECURSIVE w AS "
+                                         "( "
+                                       "SELECT d1.objid, d2.refobjid, c2.relkind AS refrelkind "
+                                         "FROM pg_depend d1 "
+                                         "JOIN pg_class c1 ON c1.oid = d1.objid "
+                                         "AND c1.relkind = 'm' "
+                                         "JOIN pg_rewrite r1 ON r1.ev_class = d1.objid "
+                                 "JOIN pg_depend d2 ON d2.classid = 'pg_rewrite'::regclass "
+                                         "AND d2.objid = r1.oid "
+                                         "AND d2.refobjid <> d1.objid "
+                                         "JOIN pg_class c2 ON c2.oid = d2.refobjid "
+                                         "AND c2.relkind IN ('m','v') "
+                                         "WHERE d1.classid = 'pg_class'::regclass "
+                                         "UNION "
+                                         "SELECT w.objid, d3.refobjid, c3.relkind "
+                                         "FROM w "
+                                         "JOIN pg_rewrite r3 ON r3.ev_class = w.refobjid "
+                                 "JOIN pg_depend d3 ON d3.classid = 'pg_rewrite'::regclass "
+                                         "AND d3.objid = r3.oid "
+                                         "AND d3.refobjid <> w.refobjid "
+                                         "JOIN pg_class c3 ON c3.oid = d3.refobjid "
+                                         "AND c3.relkind IN ('m','v') "
+                                         ") "
+                         "SELECT 'pg_class'::regclass::oid AS classid, objid, refobjid "
+                                         "FROM w "
+                                         "WHERE refrelkind = 'm'");
+
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+       ntups = PQntuples(res);
+
+       i_classid = PQfnumber(res, "classid");
+       i_objid = PQfnumber(res, "objid");
+       i_refobjid = PQfnumber(res, "refobjid");
+
+       for (i = 0; i < ntups; i++)
+       {
+               CatalogId       objId;
+               CatalogId       refobjId;
+               DumpableObject *dobj;
+               DumpableObject *refdobj;
+               TableInfo  *tbinfo;
+               TableInfo  *reftbinfo;
+
+               objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
+               objId.oid = atooid(PQgetvalue(res, i, i_objid));
+               refobjId.tableoid = objId.tableoid;
+               refobjId.oid = atooid(PQgetvalue(res, i, i_refobjid));
+
+               dobj = findObjectByCatalogId(objId);
+               if (dobj == NULL)
+                       continue;
+
+               Assert(dobj->objType == DO_TABLE);
+               tbinfo = (TableInfo *) dobj;
+               Assert(tbinfo->relkind == RELKIND_MATVIEW);
+               dobj = (DumpableObject *) tbinfo->dataObj;
+               if (dobj == NULL)
+                       continue;
+               Assert(dobj->objType == DO_REFRESH_MATVIEW);
+
+               refdobj = findObjectByCatalogId(refobjId);
+               if (refdobj == NULL)
+                       continue;
+
+               Assert(refdobj->objType == DO_TABLE);
+               reftbinfo = (TableInfo *) refdobj;
+               Assert(reftbinfo->relkind == RELKIND_MATVIEW);
+               refdobj = (DumpableObject *) reftbinfo->dataObj;
+               if (refdobj == NULL)
+                       continue;
+               Assert(refdobj->objType == DO_REFRESH_MATVIEW);
+
+               addObjectDependency(dobj, refdobj->dumpId);
+
+               if (!reftbinfo->relispopulated)
+                       tbinfo->relispopulated = false;
+       }
+
+       PQclear(res);
+
+       destroyPQExpBuffer(query);
+}
+
 /*
  * getTableDataFKConstraints -
  *       add dump-order dependencies reflecting foreign key constraints
@@ -1785,13 +2142,13 @@ guessConstraintInheritance(TableInfo *tblinfo, int numTables)
  *     dump the database definition
  */
 static void
-dumpDatabase(Archive *AH)
+dumpDatabase(Archive *fout)
 {
        PQExpBuffer dbQry = createPQExpBuffer();
        PQExpBuffer delQry = createPQExpBuffer();
        PQExpBuffer creaQry = createPQExpBuffer();
+       PGconn     *conn = GetConnection(fout);
        PGresult   *res;
-       int                     ntups;
        int                     i_tableoid,
                                i_oid,
                                i_dba,
@@ -1810,16 +2167,16 @@ dumpDatabase(Archive *AH)
                           *tablespace;
        uint32          frozenxid;
 
-       datname = PQdb(g_conn);
+       datname = PQdb(conn);
 
        if (g_verbose)
                write_msg(NULL, "saving database definition\n");
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /* Get the database owner and parameters from pg_database */
-       if (g_fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
@@ -1831,9 +2188,9 @@ dumpDatabase(Archive *AH)
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
                                                  username_subquery);
-               appendStringLiteralAH(dbQry, datname, AH);
+               appendStringLiteralAH(dbQry, datname, fout);
        }
-       else if (g_fout->remoteVersion >= 80200)
+       else if (fout->remoteVersion >= 80200)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
@@ -1845,9 +2202,9 @@ dumpDatabase(Archive *AH)
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
                                                  username_subquery);
-               appendStringLiteralAH(dbQry, datname, AH);
+               appendStringLiteralAH(dbQry, datname, fout);
        }
-       else if (g_fout->remoteVersion >= 80000)
+       else if (fout->remoteVersion >= 80000)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
@@ -1857,9 +2214,9 @@ dumpDatabase(Archive *AH)
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
                                                  username_subquery);
-               appendStringLiteralAH(dbQry, datname, AH);
+               appendStringLiteralAH(dbQry, datname, fout);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(dbQry, "SELECT tableoid, oid, "
                                                  "(%s datdba) AS dba, "
@@ -1870,7 +2227,7 @@ dumpDatabase(Archive *AH)
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
                                                  username_subquery);
-               appendStringLiteralAH(dbQry, datname, AH);
+               appendStringLiteralAH(dbQry, datname, fout);
        }
        else
        {
@@ -1885,27 +2242,10 @@ dumpDatabase(Archive *AH)
                                                  "FROM pg_database "
                                                  "WHERE datname = ",
                                                  username_subquery);
-               appendStringLiteralAH(dbQry, datname, AH);
-       }
-
-       res = PQexec(g_conn, dbQry->data);
-       check_sql_result(res, g_conn, dbQry->data, PGRES_TUPLES_OK);
-
-       ntups = PQntuples(res);
-
-       if (ntups <= 0)
-       {
-               write_msg(NULL, "missing pg_database entry for database \"%s\"\n",
-                                 datname);
-               exit_nicely();
+               appendStringLiteralAH(dbQry, datname, fout);
        }
 
-       if (ntups != 1)
-       {
-               write_msg(NULL, "query returned more than one (%d) pg_database entry for database \"%s\"\n",
-                                 ntups, datname);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, dbQry->data);
 
        i_tableoid = PQfnumber(res, "tableoid");
        i_oid = PQfnumber(res, "oid");
@@ -1929,33 +2269,33 @@ dumpDatabase(Archive *AH)
                                          fmtId(datname));
        if (strlen(encoding) > 0)
        {
-               appendPQExpBuffer(creaQry, " ENCODING = ");
-               appendStringLiteralAH(creaQry, encoding, AH);
+               appendPQExpBufferStr(creaQry, " ENCODING = ");
+               appendStringLiteralAH(creaQry, encoding, fout);
        }
        if (strlen(collate) > 0)
        {
-               appendPQExpBuffer(creaQry, " LC_COLLATE = ");
-               appendStringLiteralAH(creaQry, collate, AH);
+               appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
+               appendStringLiteralAH(creaQry, collate, fout);
        }
        if (strlen(ctype) > 0)
        {
-               appendPQExpBuffer(creaQry, " LC_CTYPE = ");
-               appendStringLiteralAH(creaQry, ctype, AH);
+               appendPQExpBufferStr(creaQry, " LC_CTYPE = ");
+               appendStringLiteralAH(creaQry, ctype, fout);
        }
        if (strlen(tablespace) > 0 && strcmp(tablespace, "pg_default") != 0)
                appendPQExpBuffer(creaQry, " TABLESPACE = %s",
                                                  fmtId(tablespace));
-       appendPQExpBuffer(creaQry, ";\n");
+       appendPQExpBufferStr(creaQry, ";\n");
 
        if (binary_upgrade)
        {
-               appendPQExpBuffer(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
+               appendPQExpBufferStr(creaQry, "\n-- For binary upgrade, set datfrozenxid.\n");
                appendPQExpBuffer(creaQry, "UPDATE pg_catalog.pg_database\n"
                                                  "SET datfrozenxid = '%u'\n"
                                                  "WHERE        datname = ",
                                                  frozenxid);
-               appendStringLiteralAH(creaQry, datname, AH);
-               appendPQExpBuffer(creaQry, ";\n");
+               appendStringLiteralAH(creaQry, datname, fout);
+               appendPQExpBufferStr(creaQry, ";\n");
 
        }
 
@@ -1964,7 +2304,7 @@ dumpDatabase(Archive *AH)
 
        dbDumpId = createDumpId();
 
-       ArchiveEntry(AH,
+       ArchiveEntry(fout,
                                 dbCatId,               /* catalog ID */
                                 dbDumpId,              /* dump ID */
                                 datname,               /* Name */
@@ -2001,24 +2341,17 @@ dumpDatabase(Archive *AH)
                                                  "WHERE oid = %u;\n",
                                                  LargeObjectRelationId);
 
-               lo_res = PQexec(g_conn, loFrozenQry->data);
-               check_sql_result(lo_res, g_conn, loFrozenQry->data, PGRES_TUPLES_OK);
-
-               if (PQntuples(lo_res) != 1)
-               {
-                       write_msg(NULL, "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n");
-                       exit_nicely();
-               }
+               lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
 
                i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
 
-               appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
+               appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject.relfrozenxid\n");
                appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
                                                  "SET relfrozenxid = '%u'\n"
                                                  "WHERE oid = %u;\n",
                                                  atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
                                                  LargeObjectRelationId);
-               ArchiveEntry(AH, nilCatalogId, createDumpId(),
+               ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                         "pg_largeobject", NULL, NULL, "",
                                         false, "pg_largeobject", SECTION_PRE_DATA,
                                         loOutQry->data, "", NULL,
@@ -2030,7 +2363,7 @@ dumpDatabase(Archive *AH)
                /*
                 * pg_largeobject_metadata
                 */
-               if (g_fout->remoteVersion >= 90000)
+               if (fout->remoteVersion >= 90000)
                {
                        resetPQExpBuffer(loFrozenQry);
                        resetPQExpBuffer(loOutQry);
@@ -2040,24 +2373,17 @@ dumpDatabase(Archive *AH)
                                                          "WHERE oid = %u;\n",
                                                          LargeObjectMetadataRelationId);
 
-                       lo_res = PQexec(g_conn, loFrozenQry->data);
-                       check_sql_result(lo_res, g_conn, loFrozenQry->data, PGRES_TUPLES_OK);
-
-                       if (PQntuples(lo_res) != 1)
-                       {
-                               write_msg(NULL, "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n");
-                               exit_nicely();
-                       }
+                       lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data);
 
                        i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid");
 
-                       appendPQExpBuffer(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
+                       appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata.relfrozenxid\n");
                        appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n"
                                                          "SET relfrozenxid = '%u'\n"
                                                          "WHERE oid = %u;\n",
                                                          atoi(PQgetvalue(lo_res, 0, i_relfrozenxid)),
                                                          LargeObjectMetadataRelationId);
-                       ArchiveEntry(AH, nilCatalogId, createDumpId(),
+                       ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 "pg_largeobject_metadata", NULL, NULL, "",
                                                 false, "pg_largeobject_metadata", SECTION_PRE_DATA,
                                                 loOutQry->data, "", NULL,
@@ -2072,7 +2398,7 @@ dumpDatabase(Archive *AH)
        }
 
        /* Dump DB comment if any */
-       if (g_fout->remoteVersion >= 80200)
+       if (fout->remoteVersion >= 80200)
        {
                /*
                 * 8.2 keeps comments on shared objects in a shared table, so we
@@ -2089,10 +2415,10 @@ dumpDatabase(Archive *AH)
                         * database.
                         */
                        appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
-                       appendStringLiteralAH(dbQry, comment, AH);
-                       appendPQExpBuffer(dbQry, ";\n");
+                       appendStringLiteralAH(dbQry, comment, fout);
+                       appendPQExpBufferStr(dbQry, ";\n");
 
-                       ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
+                       ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
                                                 dba, false, "COMMENT", SECTION_NONE,
                                                 dbQry->data, "", NULL,
                                                 &dbDumpId, 1, NULL, NULL);
@@ -2102,24 +2428,23 @@ dumpDatabase(Archive *AH)
        {
                resetPQExpBuffer(dbQry);
                appendPQExpBuffer(dbQry, "DATABASE %s", fmtId(datname));
-               dumpComment(AH, dbQry->data, NULL, "",
+               dumpComment(fout, dbQry->data, NULL, "",
                                        dbCatId, 0, dbDumpId);
        }
 
        PQclear(res);
 
        /* Dump shared security label. */
-       if (!no_security_labels && g_fout->remoteVersion >= 90200)
+       if (!no_security_labels && fout->remoteVersion >= 90200)
        {
                PQExpBuffer seclabelQry = createPQExpBuffer();
 
-               buildShSecLabelQuery(g_conn, "pg_database", dbCatId.oid, seclabelQry);
-               res = PQexec(g_conn, seclabelQry->data);
-               check_sql_result(res, g_conn, seclabelQry->data, PGRES_TUPLES_OK);
+               buildShSecLabelQuery(conn, "pg_database", dbCatId.oid, seclabelQry);
+               res = ExecuteSqlQuery(fout, seclabelQry->data, PGRES_TUPLES_OK);
                resetPQExpBuffer(seclabelQry);
-               emitShSecLabels(g_conn, res, seclabelQry, "DATABASE", datname);
+               emitShSecLabels(conn, res, seclabelQry, "DATABASE", datname);
                if (strlen(seclabelQry->data))
-                       ArchiveEntry(AH, dbCatId, createDumpId(), datname, NULL, NULL,
+                       ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
                                                 dba, false, "SECURITY LABEL", SECTION_NONE,
                                                 seclabelQry->data, "", NULL,
                                                 &dbDumpId, 1, NULL, NULL);
@@ -2144,9 +2469,9 @@ dumpEncoding(Archive *AH)
        if (g_verbose)
                write_msg(NULL, "saving encoding = %s\n", encname);
 
-       appendPQExpBuffer(qry, "SET client_encoding = ");
+       appendPQExpBufferStr(qry, "SET client_encoding = ");
        appendStringLiteralAH(qry, encname, AH);
-       appendPQExpBuffer(qry, ";\n");
+       appendPQExpBufferStr(qry, ";\n");
 
        ArchiveEntry(AH, nilCatalogId, createDumpId(),
                                 "ENCODING", NULL, NULL, "",
@@ -2191,7 +2516,7 @@ dumpStdStrings(Archive *AH)
  *     Collect schema-level data about large objects
  */
 static void
-getBlobs(Archive *AH)
+getBlobs(Archive *fout)
 {
        PQExpBuffer blobQry = createPQExpBuffer();
        BlobInfo   *binfo;
@@ -2205,25 +2530,24 @@ getBlobs(Archive *AH)
                write_msg(NULL, "reading large objects\n");
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /* Fetch BLOB OIDs, and owner/ACL data if >= 9.0 */
-       if (AH->remoteVersion >= 90000)
+       if (fout->remoteVersion >= 90000)
                appendPQExpBuffer(blobQry,
                                                  "SELECT oid, (%s lomowner) AS rolname, lomacl"
                                                  " FROM pg_largeobject_metadata",
                                                  username_subquery);
-       else if (AH->remoteVersion >= 70100)
-               appendPQExpBuffer(blobQry,
-                                                 "SELECT DISTINCT loid, NULL::oid, NULL::oid"
-                                                 " FROM pg_largeobject");
+       else if (fout->remoteVersion >= 70100)
+               appendPQExpBufferStr(blobQry,
+                                                        "SELECT DISTINCT loid, NULL::oid, NULL::oid"
+                                                        " FROM pg_largeobject");
        else
-               appendPQExpBuffer(blobQry,
-                                                 "SELECT oid, NULL::oid, NULL::oid"
-                                                 " FROM pg_class WHERE relkind = 'l'");
+               appendPQExpBufferStr(blobQry,
+                                                        "SELECT oid, NULL::oid, NULL::oid"
+                                                        " FROM pg_class WHERE relkind = 'l'");
 
-       res = PQexec(g_conn, blobQry->data);
-       check_sql_result(res, g_conn, blobQry->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, blobQry->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        if (ntups > 0)
@@ -2272,7 +2596,7 @@ getBlobs(Archive *AH)
  * dump the definition (metadata) of the given large object
  */
 static void
-dumpBlob(Archive *AH, BlobInfo *binfo)
+dumpBlob(Archive *fout, BlobInfo *binfo)
 {
        PQExpBuffer cquery = createPQExpBuffer();
        PQExpBuffer dquery = createPQExpBuffer();
@@ -2285,13 +2609,13 @@ dumpBlob(Archive *AH, BlobInfo *binfo)
                                          "SELECT pg_catalog.lo_unlink('%s');\n",
                                          binfo->dobj.name);
 
-       ArchiveEntry(AH, binfo->dobj.catId, binfo->dobj.dumpId,
+       ArchiveEntry(fout, binfo->dobj.catId, binfo->dobj.dumpId,
                                 binfo->dobj.name,
                                 NULL, NULL,
                                 binfo->rolname, false,
                                 "BLOB", SECTION_PRE_DATA,
                                 cquery->data, dquery->data, NULL,
-                                binfo->dobj.dependencies, binfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* set up tag for comment and/or ACL */
@@ -2299,18 +2623,18 @@ dumpBlob(Archive *AH, BlobInfo *binfo)
        appendPQExpBuffer(cquery, "LARGE OBJECT %s", binfo->dobj.name);
 
        /* Dump comment if any */
-       dumpComment(AH, cquery->data,
+       dumpComment(fout, cquery->data,
                                NULL, binfo->rolname,
                                binfo->dobj.catId, 0, binfo->dobj.dumpId);
 
        /* Dump security label if any */
-       dumpSecLabel(AH, cquery->data,
+       dumpSecLabel(fout, cquery->data,
                                 NULL, binfo->rolname,
                                 binfo->dobj.catId, 0, binfo->dobj.dumpId);
 
        /* Dump ACL if any */
        if (binfo->blobacl)
-               dumpACL(AH, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
+               dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
                                binfo->dobj.name, NULL, cquery->data,
                                NULL, binfo->rolname, binfo->blobacl);
 
@@ -2323,10 +2647,11 @@ dumpBlob(Archive *AH, BlobInfo *binfo)
  *     dump the data contents of all large objects
  */
 static int
-dumpBlobs(Archive *AH, void *arg)
+dumpBlobs(Archive *fout, void *arg)
 {
        const char *blobQry;
        const char *blobFetchQry;
+       PGconn     *conn = GetConnection(fout);
        PGresult   *res;
        char            buf[LOBBUFSIZE];
        int                     ntups;
@@ -2337,32 +2662,28 @@ dumpBlobs(Archive *AH, void *arg)
                write_msg(NULL, "saving large objects\n");
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /*
         * Currently, we re-fetch all BLOB OIDs using a cursor.  Consider scanning
         * the already-in-memory dumpable objects instead...
         */
-       if (AH->remoteVersion >= 90000)
+       if (fout->remoteVersion >= 90000)
                blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata";
-       else if (AH->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
                blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject";
        else
                blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_class WHERE relkind = 'l'";
 
-       res = PQexec(g_conn, blobQry);
-       check_sql_result(res, g_conn, blobQry, PGRES_COMMAND_OK);
+       ExecuteSqlStatement(fout, blobQry);
 
        /* Command to fetch from cursor */
        blobFetchQry = "FETCH 1000 IN bloboid";
 
        do
        {
-               PQclear(res);
-
                /* Do a fetch */
-               res = PQexec(g_conn, blobFetchQry);
-               check_sql_result(res, g_conn, blobFetchQry, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, blobFetchQry, PGRES_TUPLES_OK);
 
                /* Process the tuples, if any */
                ntups = PQntuples(res);
@@ -2373,51 +2694,45 @@ dumpBlobs(Archive *AH, void *arg)
 
                        blobOid = atooid(PQgetvalue(res, i, 0));
                        /* Open the BLOB */
-                       loFd = lo_open(g_conn, blobOid, INV_READ);
+                       loFd = lo_open(conn, blobOid, INV_READ);
                        if (loFd == -1)
-                       {
-                               write_msg(NULL, "could not open large object %u: %s",
-                                                 blobOid, PQerrorMessage(g_conn));
-                               exit_nicely();
-                       }
+                               exit_horribly(NULL, "could not open large object %u: %s",
+                                                         blobOid, PQerrorMessage(conn));
 
-                       StartBlob(AH, blobOid);
+                       StartBlob(fout, blobOid);
 
                        /* Now read it in chunks, sending data to archive */
                        do
                        {
-                               cnt = lo_read(g_conn, loFd, buf, LOBBUFSIZE);
+                               cnt = lo_read(conn, loFd, buf, LOBBUFSIZE);
                                if (cnt < 0)
-                               {
-                                       write_msg(NULL, "error reading large object %u: %s",
-                                                         blobOid, PQerrorMessage(g_conn));
-                                       exit_nicely();
-                               }
+                                       exit_horribly(NULL, "error reading large object %u: %s",
+                                                                 blobOid, PQerrorMessage(conn));
 
-                               WriteData(AH, buf, cnt);
+                               WriteData(fout, buf, cnt);
                        } while (cnt > 0);
 
-                       lo_close(g_conn, loFd);
+                       lo_close(conn, loFd);
 
-                       EndBlob(AH, blobOid);
+                       EndBlob(fout, blobOid);
                }
-       } while (ntups > 0);
 
-       PQclear(res);
+               PQclear(res);
+       } while (ntups > 0);
 
        return 1;
 }
 
 static void
-binary_upgrade_set_type_oids_by_type_oid(PQExpBuffer upgrade_buffer,
+binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
+                                                                                PQExpBuffer upgrade_buffer,
                                                                                 Oid pg_type_oid)
 {
        PQExpBuffer upgrade_query = createPQExpBuffer();
-       int                     ntups;
        PGresult   *upgrade_res;
        Oid                     pg_type_array_oid;
 
-       appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
+       appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n");
        appendPQExpBuffer(upgrade_buffer,
         "SELECT binary_upgrade.set_next_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                                          pg_type_oid);
@@ -2429,25 +2744,13 @@ binary_upgrade_set_type_oids_by_type_oid(PQExpBuffer upgrade_buffer,
                                          "WHERE pg_type.oid = '%u'::pg_catalog.oid;",
                                          pg_type_oid);
 
-       upgrade_res = PQexec(g_conn, upgrade_query->data);
-       check_sql_result(upgrade_res, g_conn, upgrade_query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(upgrade_res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, upgrade_query->data);
-               exit_nicely();
-       }
+       upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
 
        pg_type_array_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "typarray")));
 
        if (OidIsValid(pg_type_array_oid))
        {
-               appendPQExpBuffer(upgrade_buffer,
+               appendPQExpBufferStr(upgrade_buffer,
                           "\n-- For binary upgrade, must preserve pg_type array oid\n");
                appendPQExpBuffer(upgrade_buffer,
                                                  "SELECT binary_upgrade.set_next_array_pg_type_oid('%u'::pg_catalog.oid);\n\n",
@@ -2459,11 +2762,11 @@ binary_upgrade_set_type_oids_by_type_oid(PQExpBuffer upgrade_buffer,
 }
 
 static bool
-binary_upgrade_set_type_oids_by_rel_oid(PQExpBuffer upgrade_buffer,
+binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
+                                                                               PQExpBuffer upgrade_buffer,
                                                                                Oid pg_rel_oid)
 {
        PQExpBuffer upgrade_query = createPQExpBuffer();
-       int                     ntups;
        PGresult   *upgrade_res;
        Oid                     pg_type_oid;
        bool            toast_set = false;
@@ -2477,23 +2780,12 @@ binary_upgrade_set_type_oids_by_rel_oid(PQExpBuffer upgrade_buffer,
                                          "WHERE c.oid = '%u'::pg_catalog.oid;",
                                          pg_rel_oid);
 
-       upgrade_res = PQexec(g_conn, upgrade_query->data);
-       check_sql_result(upgrade_res, g_conn, upgrade_query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(upgrade_res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, upgrade_query->data);
-               exit_nicely();
-       }
+       upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
 
        pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel")));
 
-       binary_upgrade_set_type_oids_by_type_oid(upgrade_buffer, pg_type_oid);
+       binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer,
+                                                                                        pg_type_oid);
 
        if (!PQgetisnull(upgrade_res, 0, PQfnumber(upgrade_res, "trel")))
        {
@@ -2501,7 +2793,7 @@ binary_upgrade_set_type_oids_by_rel_oid(PQExpBuffer upgrade_buffer,
                Oid                     pg_type_toast_oid = atooid(PQgetvalue(upgrade_res, 0,
                                                                                        PQfnumber(upgrade_res, "trel")));
 
-               appendPQExpBuffer(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n");
+               appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type toast oid\n");
                appendPQExpBuffer(upgrade_buffer,
                                                  "SELECT binary_upgrade.set_next_toast_pg_type_oid('%u'::pg_catalog.oid);\n\n",
                                                  pg_type_toast_oid);
@@ -2516,41 +2808,29 @@ binary_upgrade_set_type_oids_by_rel_oid(PQExpBuffer upgrade_buffer,
 }
 
 static void
-binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer, Oid pg_class_oid,
+binary_upgrade_set_pg_class_oids(Archive *fout,
+                                                                PQExpBuffer upgrade_buffer, Oid pg_class_oid,
                                                                 bool is_index)
 {
        PQExpBuffer upgrade_query = createPQExpBuffer();
-       int                     ntups;
        PGresult   *upgrade_res;
        Oid                     pg_class_reltoastrelid;
-       Oid                     pg_class_reltoastidxid;
+       Oid                     pg_index_indexrelid;
 
        appendPQExpBuffer(upgrade_query,
-                                         "SELECT c.reltoastrelid, t.reltoastidxid "
+                                         "SELECT c.reltoastrelid, i.indexrelid "
                                          "FROM pg_catalog.pg_class c LEFT JOIN "
-                                         "pg_catalog.pg_class t ON (c.reltoastrelid = t.oid) "
+                                         "pg_catalog.pg_index i ON (c.reltoastrelid = i.indrelid AND i.indisvalid) "
                                          "WHERE c.oid = '%u'::pg_catalog.oid;",
                                          pg_class_oid);
 
-       upgrade_res = PQexec(g_conn, upgrade_query->data);
-       check_sql_result(upgrade_res, g_conn, upgrade_query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(upgrade_res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, upgrade_query->data);
-               exit_nicely();
-       }
+       upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data);
 
        pg_class_reltoastrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastrelid")));
-       pg_class_reltoastidxid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "reltoastidxid")));
+       pg_index_indexrelid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "indexrelid")));
 
-       appendPQExpBuffer(upgrade_buffer,
-                                  "\n-- For binary upgrade, must preserve pg_class oids\n");
+       appendPQExpBufferStr(upgrade_buffer,
+                                                "\n-- For binary upgrade, must preserve pg_class oids\n");
 
        if (!is_index)
        {
@@ -2576,7 +2856,7 @@ binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer, Oid pg_class_oid,
                        /* every toast table has an index */
                        appendPQExpBuffer(upgrade_buffer,
                                                          "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
-                                                         pg_class_reltoastidxid);
+                                                         pg_index_indexrelid);
                }
        }
        else
@@ -2584,7 +2864,7 @@ binary_upgrade_set_pg_class_oids(PQExpBuffer upgrade_buffer, Oid pg_class_oid,
                                                  "SELECT binary_upgrade.set_next_index_pg_class_oid('%u'::pg_catalog.oid);\n",
                                                  pg_class_oid);
 
-       appendPQExpBuffer(upgrade_buffer, "\n");
+       appendPQExpBufferChar(upgrade_buffer, '\n');
 
        PQclear(upgrade_res);
        destroyPQExpBuffer(upgrade_query);
@@ -2619,12 +2899,9 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
                extobj = NULL;
        }
        if (extobj == NULL)
-       {
-               write_msg(NULL, "could not find parent extension for %s", objlabel);
-               exit_nicely();
-       }
+               exit_horribly(NULL, "could not find parent extension for %s\n", objlabel);
 
-       appendPQExpBuffer(upgrade_buffer,
+       appendPQExpBufferStr(upgrade_buffer,
          "\n-- For binary upgrade, handle extension membership the hard way\n");
        appendPQExpBuffer(upgrade_buffer, "ALTER EXTENSION %s ADD %s;\n",
                                          fmtId(extobj->name),
@@ -2639,7 +2916,7 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
  *     numNamespaces is set to the number of namespaces read in
  */
 NamespaceInfo *
-getNamespaces(int *numNamespaces)
+getNamespaces(Archive *fout, int *numNamespaces)
 {
        PGresult   *res;
        int                     ntups;
@@ -2656,7 +2933,7 @@ getNamespaces(int *numNamespaces)
         * Before 7.3, there are no real namespaces; create two dummy entries, one
         * for user stuff and one for system stuff.
         */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
        {
                nsinfo = (NamespaceInfo *) pg_malloc(2 * sizeof(NamespaceInfo));
 
@@ -2680,8 +2957,7 @@ getNamespaces(int *numNamespaces)
 
                selectDumpableNamespace(&nsinfo[1]);
 
-               g_namespaces = nsinfo;
-               g_numNamespaces = *numNamespaces = 2;
+               *numNamespaces = 2;
 
                return nsinfo;
        }
@@ -2689,7 +2965,7 @@ getNamespaces(int *numNamespaces)
        query = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /*
         * we fetch all namespaces including system ones, so that every object we
@@ -2700,8 +2976,7 @@ getNamespaces(int *numNamespaces)
                                          "nspacl FROM pg_namespace",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -2734,8 +3009,7 @@ getNamespaces(int *numNamespaces)
        PQclear(res);
        destroyPQExpBuffer(query);
 
-       g_namespaces = nsinfo;
-       g_numNamespaces = *numNamespaces = ntups;
+       *numNamespaces = ntups;
 
        return nsinfo;
 }
@@ -2746,36 +3020,34 @@ getNamespaces(int *numNamespaces)
  *             getNamespaces
  *
  * NB: for pre-7.3 source database, we use object OID to guess whether it's
- * a system object or not.     In 7.3 and later there is no guessing.
+ * a system object or not.     In 7.3 and later there is no guessing, and we
+ * don't use objoid at all.
  */
 static NamespaceInfo *
-findNamespace(Oid nsoid, Oid objoid)
+findNamespace(Archive *fout, Oid nsoid, Oid objoid)
 {
-       int                     i;
+       NamespaceInfo *nsinfo;
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
-               for (i = 0; i < g_numNamespaces; i++)
-               {
-                       NamespaceInfo *nsinfo = &g_namespaces[i];
-
-                       if (nsoid == nsinfo->dobj.catId.oid)
-                               return nsinfo;
-               }
-               write_msg(NULL, "schema with OID %u does not exist\n", nsoid);
-               exit_nicely();
+               nsinfo = findNamespaceByOid(nsoid);
        }
        else
        {
-               /* This code depends on the layout set up by getNamespaces. */
+               /* This code depends on the dummy objects set up by getNamespaces. */
+               Oid                     i;
+
                if (objoid > g_last_builtin_oid)
                        i = 0;                          /* user object */
                else
                        i = 1;                          /* system object */
-               return &g_namespaces[i];
+               nsinfo = findNamespaceByOid(i);
        }
 
-       return NULL;                            /* keep compiler quiet */
+       if (nsinfo == NULL)
+               exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid);
+
+       return nsinfo;
 }
 
 /*
@@ -2786,7 +3058,7 @@ findNamespace(Oid nsoid, Oid objoid)
  *     numExtensions is set to the number of extensions read in
  */
 ExtensionInfo *
-getExtensions(int *numExtensions)
+getExtensions(Archive *fout, int *numExtensions)
 {
        PGresult   *res;
        int                     ntups;
@@ -2805,7 +3077,7 @@ getExtensions(int *numExtensions)
        /*
         * Before 9.1, there are no extensions.
         */
-       if (g_fout->remoteVersion < 90100)
+       if (fout->remoteVersion < 90100)
        {
                *numExtensions = 0;
                return NULL;
@@ -2814,15 +3086,14 @@ getExtensions(int *numExtensions)
        query = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       appendPQExpBuffer(query, "SELECT x.tableoid, x.oid, "
-                                         "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
-                                         "FROM pg_extension x "
-                                         "JOIN pg_namespace n ON n.oid = x.extnamespace");
+       appendPQExpBufferStr(query, "SELECT x.tableoid, x.oid, "
+                                                "x.extname, n.nspname, x.extrelocatable, x.extversion, x.extconfig, x.extcondition "
+                                                "FROM pg_extension x "
+                                                "JOIN pg_namespace n ON n.oid = x.extnamespace");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -2873,7 +3144,7 @@ getExtensions(int *numExtensions)
  * findFuncByOid().
  */
 TypeInfo *
-getTypes(int *numTypes)
+getTypes(Archive *fout, int *numTypes)
 {
        PGresult   *res;
        int                     ntups;
@@ -2885,6 +3156,7 @@ getTypes(int *numTypes)
        int                     i_oid;
        int                     i_typname;
        int                     i_typnamespace;
+       int                     i_typacl;
        int                     i_rolname;
        int                     i_typinput;
        int                     i_typoutput;
@@ -2912,12 +3184,27 @@ getTypes(int *numTypes)
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 90200)
+       {
+               appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
+                                                 "typnamespace, typacl, "
+                                                 "(%s typowner) AS rolname, "
+                                                 "typinput::oid AS typinput, "
+                                                 "typoutput::oid AS typoutput, typelem, typrelid, "
+                                                 "CASE WHEN typrelid = 0 THEN ' '::\"char\" "
+                                                 "ELSE (SELECT relkind FROM pg_class WHERE oid = typrelid) END AS typrelkind, "
+                                                 "typtype, typisdefined, "
+                                                 "typname[0] = '_' AND typelem != 0 AND "
+                                                 "(SELECT typarray FROM pg_type te WHERE oid = pg_type.typelem) = oid AS isarray "
+                                                 "FROM pg_type",
+                                                 username_subquery);
+       }
+       else if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
-                                                 "typnamespace, "
+                                                 "typnamespace, '{=U}' AS typacl, "
                                                  "(%s typowner) AS rolname, "
                                                  "typinput::oid AS typinput, "
                                                  "typoutput::oid AS typoutput, typelem, typrelid, "
@@ -2929,10 +3216,10 @@ getTypes(int *numTypes)
                                                  "FROM pg_type",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
-                                                 "typnamespace, "
+                                                 "typnamespace, '{=U}' AS typacl, "
                                                  "(%s typowner) AS rolname, "
                                                  "typinput::oid AS typinput, "
                                                  "typoutput::oid AS typoutput, typelem, typrelid, "
@@ -2943,10 +3230,10 @@ getTypes(int *numTypes)
                                                  "FROM pg_type",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
-                                                 "0::oid AS typnamespace, "
+                                                 "0::oid AS typnamespace, '{=U}' AS typacl, "
                                                  "(%s typowner) AS rolname, "
                                                  "typinput::oid AS typinput, "
                                                  "typoutput::oid AS typoutput, typelem, typrelid, "
@@ -2962,7 +3249,7 @@ getTypes(int *numTypes)
                appendPQExpBuffer(query, "SELECT "
                 "(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, "
                                                  "oid, typname, "
-                                                 "0::oid AS typnamespace, "
+                                                 "0::oid AS typnamespace, '{=U}' AS typacl, "
                                                  "(%s typowner) AS rolname, "
                                                  "typinput::oid AS typinput, "
                                                  "typoutput::oid AS typoutput, typelem, typrelid, "
@@ -2974,8 +3261,7 @@ getTypes(int *numTypes)
                                                  username_subquery);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -2985,6 +3271,7 @@ getTypes(int *numTypes)
        i_oid = PQfnumber(res, "oid");
        i_typname = PQfnumber(res, "typname");
        i_typnamespace = PQfnumber(res, "typnamespace");
+       i_typacl = PQfnumber(res, "typacl");
        i_rolname = PQfnumber(res, "rolname");
        i_typinput = PQfnumber(res, "typinput");
        i_typoutput = PQfnumber(res, "typoutput");
@@ -3002,9 +3289,12 @@ getTypes(int *numTypes)
                tyinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&tyinfo[i].dobj);
                tyinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_typname));
-               tyinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_typnamespace)),
-                                                                                                tyinfo[i].dobj.catId.oid);
+               tyinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_typnamespace)),
+                                                 tyinfo[i].dobj.catId.oid);
                tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
+               tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
                tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem));
                tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid));
                tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind);
@@ -3030,12 +3320,12 @@ getTypes(int *numTypes)
                tyinfo[i].nDomChecks = 0;
                tyinfo[i].domChecks = NULL;
                if (tyinfo[i].dobj.dump && tyinfo[i].typtype == TYPTYPE_DOMAIN)
-                       getDomainConstraints(&(tyinfo[i]));
+                       getDomainConstraints(fout, &(tyinfo[i]));
 
                /*
                 * If it's a base type, make a DumpableObject representing a shell
                 * definition of the type.      We will need to dump that ahead of the I/O
-                * functions for the type.  Similarly, range types need a shell
+                * functions for the type.      Similarly, range types need a shell
                 * definition in case they have a canonicalize function.
                 *
                 * Note: the shell type doesn't have a catId.  You might think it
@@ -3067,7 +3357,7 @@ getTypes(int *numTypes)
                         * typinput and typoutput since the other functions only exist
                         * post-7.3.
                         */
-                       if (g_fout->remoteVersion < 70300)
+                       if (fout->remoteVersion < 70300)
                        {
                                Oid                     typinput;
                                Oid                     typoutput;
@@ -3126,7 +3416,7 @@ getTypes(int *numTypes)
  *     numOprs is set to the number of operators read in
  */
 OprInfo *
-getOperators(int *numOprs)
+getOperators(Archive *fout, int *numOprs)
 {
        PGresult   *res;
        int                     ntups;
@@ -3147,9 +3437,9 @@ getOperators(int *numOprs)
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                                                  "oprnamespace, "
@@ -3159,7 +3449,7 @@ getOperators(int *numOprs)
                                                  "FROM pg_operator",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, oprname, "
                                                  "0::oid AS oprnamespace, "
@@ -3182,8 +3472,7 @@ getOperators(int *numOprs)
                                                  username_subquery);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numOprs = ntups;
@@ -3205,8 +3494,10 @@ getOperators(int *numOprs)
                oprinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&oprinfo[i].dobj);
                oprinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_oprname));
-               oprinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_oprnamespace)),
-                                                                                                 oprinfo[i].dobj.catId.oid);
+               oprinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_oprnamespace)),
+                                                 oprinfo[i].dobj.catId.oid);
                oprinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                oprinfo[i].oprkind = (PQgetvalue(res, i, i_oprkind))[0];
                oprinfo[i].oprcode = atooid(PQgetvalue(res, i, i_oprcode));
@@ -3234,12 +3525,12 @@ getOperators(int *numOprs)
  *     numCollations is set to the number of collations read in
  */
 CollInfo *
-getCollations(int *numCollations)
+getCollations(Archive *fout, int *numCollations)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        CollInfo   *collinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -3248,19 +3539,21 @@ getCollations(int *numCollations)
        int                     i_rolname;
 
        /* Collations didn't exist pre-9.1 */
-       if (g_fout->remoteVersion < 90100)
+       if (fout->remoteVersion < 90100)
        {
                *numCollations = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /*
         * find all collations, including builtin collations; we filter out
         * system-defined collations at dump-out time.
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, collname, "
                                          "collnamespace, "
@@ -3268,8 +3561,7 @@ getCollations(int *numCollations)
                                          "FROM pg_collation",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numCollations = ntups;
@@ -3289,8 +3581,10 @@ getCollations(int *numCollations)
                collinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&collinfo[i].dobj);
                collinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_collname));
-               collinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_collnamespace)),
-                                                                                                collinfo[i].dobj.catId.oid);
+               collinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_collnamespace)),
+                                                 collinfo[i].dobj.catId.oid);
                collinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
                /* Decide whether we want to dump it */
@@ -3312,12 +3606,12 @@ getCollations(int *numCollations)
  *     numConversions is set to the number of conversions read in
  */
 ConvInfo *
-getConversions(int *numConversions)
+getConversions(Archive *fout, int *numConversions)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        ConvInfo   *convinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -3326,19 +3620,21 @@ getConversions(int *numConversions)
        int                     i_rolname;
 
        /* Conversions didn't exist pre-7.3 */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
        {
                *numConversions = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /*
         * find all conversions, including builtin conversions; we filter out
         * system-defined conversions at dump-out time.
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                                          "connamespace, "
@@ -3346,8 +3642,7 @@ getConversions(int *numConversions)
                                          "FROM pg_conversion",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numConversions = ntups;
@@ -3367,8 +3662,10 @@ getConversions(int *numConversions)
                convinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&convinfo[i].dobj);
                convinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_conname));
-               convinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_connamespace)),
-                                                                                                convinfo[i].dobj.catId.oid);
+               convinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_connamespace)),
+                                                 convinfo[i].dobj.catId.oid);
                convinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
                /* Decide whether we want to dump it */
@@ -3390,7 +3687,7 @@ getConversions(int *numConversions)
  *     numOpclasses is set to the number of opclasses read in
  */
 OpclassInfo *
-getOpclasses(int *numOpclasses)
+getOpclasses(Archive *fout, int *numOpclasses)
 {
        PGresult   *res;
        int                     ntups;
@@ -3409,9 +3706,9 @@ getOpclasses(int *numOpclasses)
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
                                                  "opcnamespace, "
@@ -3419,25 +3716,24 @@ getOpclasses(int *numOpclasses)
                                                  "FROM pg_opclass",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
-               appendPQExpBuffer(query, "SELECT tableoid, oid, opcname, "
-                                                 "0::oid AS opcnamespace, "
-                                                 "''::name AS rolname "
-                                                 "FROM pg_opclass");
+               appendPQExpBufferStr(query, "SELECT tableoid, oid, opcname, "
+                                                        "0::oid AS opcnamespace, "
+                                                        "''::name AS rolname "
+                                                        "FROM pg_opclass");
        }
        else
        {
-               appendPQExpBuffer(query, "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, "
-                                                 "oid, opcname, "
-                                                 "0::oid AS opcnamespace, "
-                                                 "''::name AS rolname "
-                                                 "FROM pg_opclass");
+               appendPQExpBufferStr(query, "SELECT "
+                                                        "(SELECT oid FROM pg_class WHERE relname = 'pg_opclass') AS tableoid, "
+                                                        "oid, opcname, "
+                                                        "0::oid AS opcnamespace, "
+                                                        "''::name AS rolname "
+                                                        "FROM pg_opclass");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numOpclasses = ntups;
@@ -3457,14 +3753,16 @@ getOpclasses(int *numOpclasses)
                opcinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&opcinfo[i].dobj);
                opcinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opcname));
-               opcinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_opcnamespace)),
-                                                                                                 opcinfo[i].dobj.catId.oid);
+               opcinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_opcnamespace)),
+                                                 opcinfo[i].dobj.catId.oid);
                opcinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
                /* Decide whether we want to dump it */
                selectDumpableObject(&(opcinfo[i].dobj));
 
-               if (g_fout->remoteVersion >= 70300)
+               if (fout->remoteVersion >= 70300)
                {
                        if (strlen(opcinfo[i].rolname) == 0)
                                write_msg(NULL, "WARNING: owner of operator class \"%s\" appears to be invalid\n",
@@ -3487,7 +3785,7 @@ getOpclasses(int *numOpclasses)
  *     numOpfamilies is set to the number of opfamilies read in
  */
 OpfamilyInfo *
-getOpfamilies(int *numOpfamilies)
+getOpfamilies(Archive *fout, int *numOpfamilies)
 {
        PGresult   *res;
        int                     ntups;
@@ -3501,7 +3799,7 @@ getOpfamilies(int *numOpfamilies)
        int                     i_rolname;
 
        /* Before 8.3, there is no separate concept of opfamilies */
-       if (g_fout->remoteVersion < 80300)
+       if (fout->remoteVersion < 80300)
        {
                *numOpfamilies = 0;
                return NULL;
@@ -3515,7 +3813,7 @@ getOpfamilies(int *numOpfamilies)
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, opfname, "
                                          "opfnamespace, "
@@ -3523,8 +3821,7 @@ getOpfamilies(int *numOpfamilies)
                                          "FROM pg_opfamily",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numOpfamilies = ntups;
@@ -3544,14 +3841,16 @@ getOpfamilies(int *numOpfamilies)
                opfinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&opfinfo[i].dobj);
                opfinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_opfname));
-               opfinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_opfnamespace)),
-                                                                                                 opfinfo[i].dobj.catId.oid);
+               opfinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_opfnamespace)),
+                                                 opfinfo[i].dobj.catId.oid);
                opfinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
 
                /* Decide whether we want to dump it */
                selectDumpableObject(&(opfinfo[i].dobj));
 
-               if (g_fout->remoteVersion >= 70300)
+               if (fout->remoteVersion >= 70300)
                {
                        if (strlen(opfinfo[i].rolname) == 0)
                                write_msg(NULL, "WARNING: owner of operator family \"%s\" appears to be invalid\n",
@@ -3574,7 +3873,7 @@ getOpfamilies(int *numOpfamilies)
  * numAggs is set to the number of aggregates read in
  */
 AggInfo *
-getAggregates(int *numAggs)
+getAggregates(Archive *fout, int *numAggs)
 {
        PGresult   *res;
        int                     ntups;
@@ -3589,20 +3888,22 @@ getAggregates(int *numAggs)
        int                     i_proargtypes;
        int                     i_rolname;
        int                     i_aggacl;
+       int                     i_proiargs;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /*
         * Find all user-defined aggregates.  See comment in getFuncs() for the
         * rationale behind the filtering logic.
         */
 
-       if (g_fout->remoteVersion >= 80200)
+       if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
                                                  "pronamespace AS aggnamespace, "
                                                  "pronargs, proargtypes, "
+                       "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
                                                  "(%s proowner) AS rolname, "
                                                  "proacl AS aggacl "
                                                  "FROM pg_proc p "
@@ -3611,21 +3912,37 @@ getAggregates(int *numAggs)
                                                  "(SELECT oid FROM pg_namespace "
                                                  "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
-               if (binary_upgrade && g_fout->remoteVersion >= 90100)
-                       appendPQExpBuffer(query,
-                                                         " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
-                                                         "classid = 'pg_proc'::regclass AND "
-                                                         "objid = p.oid AND "
-                                                         "refclassid = 'pg_extension'::regclass AND "
-                                                         "deptype = 'e')");
-               appendPQExpBuffer(query, ")");
+               if (binary_upgrade && fout->remoteVersion >= 90100)
+                       appendPQExpBufferStr(query,
+                                                                " OR EXISTS(SELECT 1 FROM pg_depend WHERE "
+                                                                "classid = 'pg_proc'::regclass AND "
+                                                                "objid = p.oid AND "
+                                                                "refclassid = 'pg_extension'::regclass AND "
+                                                                "deptype = 'e')");
+               appendPQExpBufferChar(query, ')');
+       }
+       else if (fout->remoteVersion >= 80200)
+       {
+               appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
+                                                 "pronamespace AS aggnamespace, "
+                                                 "pronargs, proargtypes, "
+                                                 "NULL::text AS proiargs,"
+                                                 "(%s proowner) AS rolname, "
+                                                 "proacl AS aggacl "
+                                                 "FROM pg_proc p "
+                                                 "WHERE proisagg AND ("
+                                                 "pronamespace != "
+                                                 "(SELECT oid FROM pg_namespace "
+                                                 "WHERE nspname = 'pg_catalog'))",
+                                                 username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
                                                  "pronamespace AS aggnamespace, "
                                                  "CASE WHEN proargtypes[0] = 'pg_catalog.\"any\"'::pg_catalog.regtype THEN 0 ELSE 1 END AS pronargs, "
                                                  "proargtypes, "
+                                                 "NULL::text AS proiargs, "
                                                  "(%s proowner) AS rolname, "
                                                  "proacl AS aggacl "
                                                  "FROM pg_proc "
@@ -3634,12 +3951,13 @@ getAggregates(int *numAggs)
                           "(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, aggname, "
                                                  "0::oid AS aggnamespace, "
                                  "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
                                                  "aggbasetype AS proargtypes, "
+                                                 "NULL::text AS proiargs, "
                                                  "(%s aggowner) AS rolname, "
                                                  "'{=X}' AS aggacl "
                                                  "FROM pg_aggregate "
@@ -3655,6 +3973,7 @@ getAggregates(int *numAggs)
                                                  "0::oid AS aggnamespace, "
                                  "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
                                                  "aggbasetype AS proargtypes, "
+                                                 "NULL::text AS proiargs, "
                                                  "(%s aggowner) AS rolname, "
                                                  "'{=X}' AS aggacl "
                                                  "FROM pg_aggregate "
@@ -3663,8 +3982,7 @@ getAggregates(int *numAggs)
                                                  g_last_builtin_oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numAggs = ntups;
@@ -3679,6 +3997,7 @@ getAggregates(int *numAggs)
        i_proargtypes = PQfnumber(res, "proargtypes");
        i_rolname = PQfnumber(res, "rolname");
        i_aggacl = PQfnumber(res, "aggacl");
+       i_proiargs = PQfnumber(res, "proiargs");
 
        for (i = 0; i < ntups; i++)
        {
@@ -3687,8 +4006,10 @@ getAggregates(int *numAggs)
                agginfo[i].aggfn.dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&agginfo[i].aggfn.dobj);
                agginfo[i].aggfn.dobj.name = pg_strdup(PQgetvalue(res, i, i_aggname));
-               agginfo[i].aggfn.dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_aggnamespace)),
-                                                                                       agginfo[i].aggfn.dobj.catId.oid);
+               agginfo[i].aggfn.dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_aggnamespace)),
+                                                 agginfo[i].aggfn.dobj.catId.oid);
                agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                if (strlen(agginfo[i].aggfn.rolname) == 0)
                        write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n",
@@ -3696,13 +4017,14 @@ getAggregates(int *numAggs)
                agginfo[i].aggfn.lang = InvalidOid;             /* not currently interesting */
                agginfo[i].aggfn.prorettype = InvalidOid;               /* not saved */
                agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl));
+               agginfo[i].aggfn.proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
                agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs));
                if (agginfo[i].aggfn.nargs == 0)
                        agginfo[i].aggfn.argtypes = NULL;
                else
                {
                        agginfo[i].aggfn.argtypes = (Oid *) pg_malloc(agginfo[i].aggfn.nargs * sizeof(Oid));
-                       if (g_fout->remoteVersion >= 70300)
+                       if (fout->remoteVersion >= 70300)
                                parseOidArray(PQgetvalue(res, i, i_proargtypes),
                                                          agginfo[i].aggfn.argtypes,
                                                          agginfo[i].aggfn.nargs);
@@ -3730,7 +4052,7 @@ getAggregates(int *numAggs)
  * numFuncs is set to the number of functions read in
  */
 FuncInfo *
-getFuncs(int *numFuncs)
+getFuncs(Archive *fout, int *numFuncs)
 {
        PGresult   *res;
        int                     ntups;
@@ -3747,9 +4069,10 @@ getFuncs(int *numFuncs)
        int                     i_proargtypes;
        int                     i_prorettype;
        int                     i_proacl;
+       int                     i_proiargs;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /*
         * Find all user-defined functions.  Normally we can exclude functions in
@@ -3767,12 +4090,13 @@ getFuncs(int *numFuncs)
         * doesn't have; otherwise we might not get creation ordering correct.
         */
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query,
                                                  "SELECT tableoid, oid, proname, prolang, "
                                                  "pronargs, proargtypes, prorettype, proacl, "
                                                  "pronamespace, "
+                       "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
                                                  "(%s proowner) AS rolname "
                                                  "FROM pg_proc p "
                                                  "WHERE NOT proisagg AND ("
@@ -3780,27 +4104,43 @@ getFuncs(int *numFuncs)
                                                  "(SELECT oid FROM pg_namespace "
                                                  "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
-               if (g_fout->remoteVersion >= 90200)
-                       appendPQExpBuffer(query,
-                                                         "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
-                                                         "WHERE classid = 'pg_proc'::regclass AND "
-                                                         "objid = p.oid AND deptype = 'i')");
-               if (binary_upgrade && g_fout->remoteVersion >= 90100)
-                       appendPQExpBuffer(query,
-                                                         "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
-                                                         "classid = 'pg_proc'::regclass AND "
-                                                         "objid = p.oid AND "
-                                                         "refclassid = 'pg_extension'::regclass AND "
-                                                         "deptype = 'e')");
-               appendPQExpBuffer(query, ")");
+               if (fout->remoteVersion >= 90200)
+                       appendPQExpBufferStr(query,
+                                                                "\n  AND NOT EXISTS (SELECT 1 FROM pg_depend "
+                                                                "WHERE classid = 'pg_proc'::regclass AND "
+                                                                "objid = p.oid AND deptype = 'i')");
+               if (binary_upgrade && fout->remoteVersion >= 90100)
+                       appendPQExpBufferStr(query,
+                                                                "\n  OR EXISTS(SELECT 1 FROM pg_depend WHERE "
+                                                                "classid = 'pg_proc'::regclass AND "
+                                                                "objid = p.oid AND "
+                                                                "refclassid = 'pg_extension'::regclass AND "
+                                                                "deptype = 'e')");
+               appendPQExpBufferChar(query, ')');
+       }
+       else if (fout->remoteVersion >= 70300)
+       {
+               appendPQExpBuffer(query,
+                                                 "SELECT tableoid, oid, proname, prolang, "
+                                                 "pronargs, proargtypes, prorettype, proacl, "
+                                                 "pronamespace, "
+                                                 "NULL::text AS proiargs,"
+                                                 "(%s proowner) AS rolname "
+                                                 "FROM pg_proc p "
+                                                 "WHERE NOT proisagg AND ("
+                                                 "pronamespace != "
+                                                 "(SELECT oid FROM pg_namespace "
+                                                 "WHERE nspname = 'pg_catalog'))",
+                                                 username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query,
                                                  "SELECT tableoid, oid, proname, prolang, "
                                                  "pronargs, proargtypes, prorettype, "
                                                  "'{=X}' AS proacl, "
                                                  "0::oid AS pronamespace, "
+                                                 "NULL::text AS proiargs,"
                                                  "(%s proowner) AS rolname "
                                                  "FROM pg_proc "
                                                  "WHERE pg_proc.oid > '%u'::oid",
@@ -3817,6 +4157,7 @@ getFuncs(int *numFuncs)
                                                  "pronargs, proargtypes, prorettype, "
                                                  "'{=X}' AS proacl, "
                                                  "0::oid AS pronamespace, "
+                                                 "NULL::text AS proiargs,"
                                                  "(%s proowner) AS rolname "
                                                  "FROM pg_proc "
                                                  "where pg_proc.oid > '%u'::oid",
@@ -3824,14 +4165,13 @@ getFuncs(int *numFuncs)
                                                  g_last_builtin_oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
        *numFuncs = ntups;
 
-       finfo = (FuncInfo *) pg_calloc(ntups, sizeof(FuncInfo));
+       finfo = (FuncInfo *) pg_malloc0(ntups * sizeof(FuncInfo));
 
        i_tableoid = PQfnumber(res, "tableoid");
        i_oid = PQfnumber(res, "oid");
@@ -3843,6 +4183,7 @@ getFuncs(int *numFuncs)
        i_proargtypes = PQfnumber(res, "proargtypes");
        i_prorettype = PQfnumber(res, "prorettype");
        i_proacl = PQfnumber(res, "proacl");
+       i_proiargs = PQfnumber(res, "proiargs");
 
        for (i = 0; i < ntups; i++)
        {
@@ -3852,11 +4193,13 @@ getFuncs(int *numFuncs)
                AssignDumpId(&finfo[i].dobj);
                finfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_proname));
                finfo[i].dobj.namespace =
-                       findNamespace(atooid(PQgetvalue(res, i, i_pronamespace)),
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_pronamespace)),
                                                  finfo[i].dobj.catId.oid);
                finfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                finfo[i].lang = atooid(PQgetvalue(res, i, i_prolang));
                finfo[i].prorettype = atooid(PQgetvalue(res, i, i_prorettype));
+               finfo[i].proiargs = pg_strdup(PQgetvalue(res, i, i_proiargs));
                finfo[i].proacl = pg_strdup(PQgetvalue(res, i, i_proacl));
                finfo[i].nargs = atoi(PQgetvalue(res, i, i_pronargs));
                if (finfo[i].nargs == 0)
@@ -3892,7 +4235,7 @@ getFuncs(int *numFuncs)
  * numTables is set to the number of tables read in
  */
 TableInfo *
-getTables(int *numTables)
+getTables(Archive *fout, int *numTables)
 {
        PGresult   *res;
        int                     ntups;
@@ -3915,24 +4258,28 @@ getTables(int *numTables)
        int                     i_toastoid;
        int                     i_toastfrozenxid;
        int                     i_relpersistence;
+       int                     i_relispopulated;
+       int                     i_relreplident;
        int                     i_owning_tab;
        int                     i_owning_col;
        int                     i_reltablespace;
        int                     i_reloptions;
+       int                     i_checkoption;
        int                     i_toastreloptions;
        int                     i_reloftype;
+       int                     i_relpages;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /*
-        * Find all the tables (including views and sequences).
+        * Find all the tables and table-like objects.
         *
         * We include system catalogs, so that we can work if a user table is
         * defined to inherit from a system catalog (pretty weird, but...)
         *
-        * We ignore tables that are not type 'r' (ordinary relation), 'S'
-        * (sequence), 'v' (view), or 'c' (composite type).
+        * We ignore relations that are not ordinary tables, sequences, views,
+        * materialized views, composite types, or foreign tables.
         *
         * Composite-type table entries won't be dumped as such, but we have to
         * make a DumpableObject for them so that we can track dependencies of the
@@ -3945,7 +4292,7 @@ getTables(int *numTables)
         * we cannot correctly identify inherited columns, owned sequences, etc.
         */
 
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90400)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -3959,12 +4306,15 @@ getTables(int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "c.relpersistence, "
+                                                 "c.relpersistence, c.relispopulated, "
+                                                 "c.relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
-                                               "array_to_string(c.reloptions, ', ') AS reloptions, "
+                                               "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, "
+                                                 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
+                                                          "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
                                                  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
                                                  "FROM pg_class c "
                                                  "LEFT JOIN pg_depend d ON "
@@ -3973,15 +4323,15 @@ getTables(int *numTables)
                                                  "d.objsubid = 0 AND "
                                                  "d.refclassid = c.tableoid AND d.deptype = 'a') "
                                           "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
-                                                 "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c') "
+                                  "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
                                                  "ORDER BY c.oid",
                                                  username_subquery,
                                                  RELKIND_SEQUENCE,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
-                                                 RELKIND_FOREIGN_TABLE);
+                                                 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
        }
-       else if (g_fout->remoteVersion >= 90000)
+       else if (fout->remoteVersion >= 90300)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -3995,12 +4345,15 @@ getTables(int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "c.relpersistence, c.relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
                                                  "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
-                                               "array_to_string(c.reloptions, ', ') AS reloptions, "
+                                               "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, "
+                                                 "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
+                                                          "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
                                                  "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
                                                  "FROM pg_class c "
                                                  "LEFT JOIN pg_depend d ON "
@@ -4009,14 +4362,15 @@ getTables(int *numTables)
                                                  "d.objsubid = 0 AND "
                                                  "d.refclassid = c.tableoid AND d.deptype = 'a') "
                                           "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
-                                                 "WHERE c.relkind in ('%c', '%c', '%c', '%c') "
+                                  "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
                                                  "ORDER BY c.oid",
                                                  username_subquery,
                                                  RELKIND_SEQUENCE,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
-                                                 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
+                                                 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
+                                                 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
        }
-       else if (g_fout->remoteVersion >= 80400)
+       else if (fout->remoteVersion >= 90100)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -4030,8 +4384,82 @@ getTables(int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
-                                                 "NULL AS reloftype, "
+                                                 "c.relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
+                                                 "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
+                                                 "d.refobjid AS owning_tab, "
+                                                 "d.refobjsubid AS owning_col, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
+                                               "array_to_string(c.reloptions, ', ') AS reloptions, "
+                                                 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+                                                 "FROM pg_class c "
+                                                 "LEFT JOIN pg_depend d ON "
+                                                 "(c.relkind = '%c' AND "
+                                                 "d.classid = c.tableoid AND d.objid = c.oid AND "
+                                                 "d.objsubid = 0 AND "
+                                                 "d.refclassid = c.tableoid AND d.deptype = 'a') "
+                                          "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
+                                  "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
+                                                 "ORDER BY c.oid",
+                                                 username_subquery,
+                                                 RELKIND_SEQUENCE,
+                                                 RELKIND_RELATION, RELKIND_SEQUENCE,
+                                                 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE,
+                                                 RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
+       }
+       else if (fout->remoteVersion >= 90000)
+       {
+               /*
+                * Left join to pick up dependency info linking sequences to their
+                * owning column, if any (note this dependency is AUTO as of 8.2)
+                */
+               appendPQExpBuffer(query,
+                                                 "SELECT c.tableoid, c.oid, c.relname, "
+                                                 "c.relacl, c.relkind, c.relnamespace, "
+                                                 "(%s c.relowner) AS rolname, "
+                                                 "c.relchecks, c.relhastriggers, "
+                                                 "c.relhasindex, c.relhasrules, c.relhasoids, "
+                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "tc.relfrozenxid AS tfrozenxid, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
+                                                 "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, "
+                                                 "d.refobjid AS owning_tab, "
+                                                 "d.refobjsubid AS owning_col, "
+                                                 "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
+                                               "array_to_string(c.reloptions, ', ') AS reloptions, "
+                                                 "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+                                                 "FROM pg_class c "
+                                                 "LEFT JOIN pg_depend d ON "
+                                                 "(c.relkind = '%c' AND "
+                                                 "d.classid = c.tableoid AND d.objid = c.oid AND "
+                                                 "d.objsubid = 0 AND "
+                                                 "d.refclassid = c.tableoid AND d.deptype = 'a') "
+                                          "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) "
+                                                 "WHERE c.relkind in ('%c', '%c', '%c', '%c') "
+                                                 "ORDER BY c.oid",
+                                                 username_subquery,
+                                                 RELKIND_SEQUENCE,
+                                                 RELKIND_RELATION, RELKIND_SEQUENCE,
+                                                 RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
+       }
+       else if (fout->remoteVersion >= 80400)
+       {
+               /*
+                * Left join to pick up dependency info linking sequences to their
+                * owning column, if any (note this dependency is AUTO as of 8.2)
+                */
+               appendPQExpBuffer(query,
+                                                 "SELECT c.tableoid, c.oid, c.relname, "
+                                                 "c.relacl, c.relkind, c.relnamespace, "
+                                                 "(%s c.relowner) AS rolname, "
+                                                 "c.relchecks, c.relhastriggers, "
+                                                 "c.relhasindex, c.relhasrules, c.relhasoids, "
+                                                 "c.relfrozenxid, tc.oid AS toid, "
+                                                 "tc.relfrozenxid AS tfrozenxid, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
+                                                 "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
                                                  "(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
@@ -4051,7 +4479,7 @@ getTables(int *numTables)
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
        }
-       else if (g_fout->remoteVersion >= 80200)
+       else if (fout->remoteVersion >= 80200)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -4061,11 +4489,12 @@ getTables(int *numTables)
                                                  "SELECT c.tableoid, c.oid, c.relname, "
                                                  "c.relacl, c.relkind, c.relnamespace, "
                                                  "(%s c.relowner) AS rolname, "
-                                                 "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, "
+                                         "c.relchecks, (c.reltriggers <> 0) AS relhastriggers, "
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4086,7 +4515,7 @@ getTables(int *numTables)
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
        }
-       else if (g_fout->remoteVersion >= 80000)
+       else if (fout->remoteVersion >= 80000)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -4101,7 +4530,8 @@ getTables(int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4121,7 +4551,7 @@ getTables(int *numTables)
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -4136,7 +4566,8 @@ getTables(int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4156,7 +4587,7 @@ getTables(int *numTables)
                                                  RELKIND_RELATION, RELKIND_SEQUENCE,
                                                  RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
        }
-       else if (g_fout->remoteVersion >= 70200)
+       else if (fout->remoteVersion >= 70200)
        {
                appendPQExpBuffer(query,
                                                  "SELECT tableoid, oid, relname, relacl, relkind, "
@@ -4167,7 +4598,8 @@ getTables(int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "NULL::oid AS owning_tab, "
                                                  "NULL::int4 AS owning_col, "
@@ -4180,7 +4612,7 @@ getTables(int *numTables)
                                                  username_subquery,
                                                  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                /* all tables have oids in 7.1 */
                appendPQExpBuffer(query,
@@ -4193,7 +4625,8 @@ getTables(int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "NULL::oid AS owning_tab, "
                                                  "NULL::int4 AS owning_col, "
@@ -4229,7 +4662,8 @@ getTables(int *numTables)
                                                  "0 as relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, 0 AS relpages, "
                                                  "NULL AS reloftype, "
                                                  "NULL::oid AS owning_tab, "
                                                  "NULL::int4 AS owning_col, "
@@ -4244,8 +4678,7 @@ getTables(int *numTables)
                                                  RELKIND_RELATION, RELKIND_SEQUENCE);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -4260,7 +4693,7 @@ getTables(int *numTables)
         * only one, because we don't yet know which tables might be inheritance
         * ancestors of the target table.
         */
-       tblinfo = (TableInfo *) pg_calloc(ntups, sizeof(TableInfo));
+       tblinfo = (TableInfo *) pg_malloc0(ntups * sizeof(TableInfo));
 
        i_reltableoid = PQfnumber(res, "tableoid");
        i_reloid = PQfnumber(res, "oid");
@@ -4278,14 +4711,18 @@ getTables(int *numTables)
        i_toastoid = PQfnumber(res, "toid");
        i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
        i_relpersistence = PQfnumber(res, "relpersistence");
+       i_relispopulated = PQfnumber(res, "relispopulated");
+       i_relreplident = PQfnumber(res, "relreplident");
+       i_relpages = PQfnumber(res, "relpages");
        i_owning_tab = PQfnumber(res, "owning_tab");
        i_owning_col = PQfnumber(res, "owning_col");
        i_reltablespace = PQfnumber(res, "reltablespace");
        i_reloptions = PQfnumber(res, "reloptions");
+       i_checkoption = PQfnumber(res, "checkoption");
        i_toastreloptions = PQfnumber(res, "toast_reloptions");
        i_reloftype = PQfnumber(res, "reloftype");
 
-       if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
+       if (lockWaitTimeout && fout->remoteVersion >= 70300)
        {
                /*
                 * Arrange to fail instead of waiting forever for a table lock.
@@ -4295,9 +4732,9 @@ getTables(int *numTables)
                 * applied to other things too.
                 */
                resetPQExpBuffer(query);
-               appendPQExpBuffer(query, "SET statement_timeout = ");
-               appendStringLiteralConn(query, lockWaitTimeout, g_conn);
-               do_sql_command(g_conn, query->data);
+               appendPQExpBufferStr(query, "SET statement_timeout = ");
+               appendStringLiteralConn(query, lockWaitTimeout, GetConnection(fout));
+               ExecuteSqlStatement(fout, query->data);
        }
 
        for (i = 0; i < ntups; i++)
@@ -4307,8 +4744,10 @@ getTables(int *numTables)
                tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
                AssignDumpId(&tblinfo[i].dobj);
                tblinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_relname));
-               tblinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_relnamespace)),
-                                                                                                 tblinfo[i].dobj.catId.oid);
+               tblinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_relnamespace)),
+                                                 tblinfo[i].dobj.catId.oid);
                tblinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                tblinfo[i].relacl = pg_strdup(PQgetvalue(res, i, i_relacl));
                tblinfo[i].relkind = *(PQgetvalue(res, i, i_relkind));
@@ -4317,6 +4756,9 @@ getTables(int *numTables)
                tblinfo[i].hasrules = (strcmp(PQgetvalue(res, i, i_relhasrules), "t") == 0);
                tblinfo[i].hastriggers = (strcmp(PQgetvalue(res, i, i_relhastriggers), "t") == 0);
                tblinfo[i].hasoids = (strcmp(PQgetvalue(res, i, i_relhasoids), "t") == 0);
+               tblinfo[i].relispopulated = (strcmp(PQgetvalue(res, i, i_relispopulated), "t") == 0);
+               tblinfo[i].relreplident = *(PQgetvalue(res, i, i_relreplident));
+               tblinfo[i].relpages = atoi(PQgetvalue(res, i, i_relpages));
                tblinfo[i].frozenxid = atooid(PQgetvalue(res, i, i_relfrozenxid));
                tblinfo[i].toast_oid = atooid(PQgetvalue(res, i, i_toastoid));
                tblinfo[i].toast_frozenxid = atooid(PQgetvalue(res, i, i_toastfrozenxid));
@@ -4337,6 +4779,10 @@ getTables(int *numTables)
                }
                tblinfo[i].reltablespace = pg_strdup(PQgetvalue(res, i, i_reltablespace));
                tblinfo[i].reloptions = pg_strdup(PQgetvalue(res, i, i_reloptions));
+               if (i_checkoption == -1 || PQgetisnull(res, i, i_checkoption))
+                       tblinfo[i].checkoption = NULL;
+               else
+                       tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption));
                tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions));
 
                /* other fields were zeroed above */
@@ -4350,6 +4796,8 @@ getTables(int *numTables)
                        selectDumpableTable(&tblinfo[i]);
                tblinfo[i].interesting = tblinfo[i].dobj.dump;
 
+               tblinfo[i].postponed_def = false; /* might get set during sort */
+
                /*
                 * Read-lock target tables to make sure they aren't DROPPED or altered
                 * in schema before we get around to dumping them.
@@ -4366,9 +4814,10 @@ getTables(int *numTables)
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query,
                                                          "LOCK TABLE %s IN ACCESS SHARE MODE",
-                                                fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name,
-                                                                               tblinfo[i].dobj.name));
-                       do_sql_command(g_conn, query->data);
+                                                         fmtQualifiedId(fout->remoteVersion,
+                                                                               tblinfo[i].dobj.namespace->dobj.name,
+                                                                                        tblinfo[i].dobj.name));
+                       ExecuteSqlStatement(fout, query->data);
                }
 
                /* Emit notice if join for owner failed */
@@ -4377,45 +4826,50 @@ getTables(int *numTables)
                                          tblinfo[i].dobj.name);
        }
 
-       if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
+       if (lockWaitTimeout && fout->remoteVersion >= 70300)
        {
-               do_sql_command(g_conn, "SET statement_timeout = 0");
+               ExecuteSqlStatement(fout, "SET statement_timeout = 0");
        }
 
        PQclear(res);
 
+       destroyPQExpBuffer(query);
+
+       return tblinfo;
+}
+
+/*
+ * getOwnedSeqs
+ *       identify owned sequences and mark them as dumpable if owning table is
+ *
+ * We used to do this in getTables(), but it's better to do it after the
+ * index used by findTableByOid() has been set up.
+ */
+void
+getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables)
+{
+       int                     i;
+
        /*
         * Force sequences that are "owned" by table columns to be dumped whenever
         * their owning table is being dumped.
         */
-       for (i = 0; i < ntups; i++)
+       for (i = 0; i < numTables; i++)
        {
                TableInfo  *seqinfo = &tblinfo[i];
-               int                     j;
+               TableInfo  *owning_tab;
 
                if (!OidIsValid(seqinfo->owning_tab))
                        continue;                       /* not an owned sequence */
                if (seqinfo->dobj.dump)
                        continue;                       /* no need to search */
-
-               /* can't use findTableByOid yet, unfortunately */
-               for (j = 0; j < ntups; j++)
+               owning_tab = findTableByOid(seqinfo->owning_tab);
+               if (owning_tab && owning_tab->dobj.dump)
                {
-                       if (tblinfo[j].dobj.catId.oid == seqinfo->owning_tab)
-                       {
-                               if (tblinfo[j].dobj.dump)
-                               {
-                                       seqinfo->interesting = true;
-                                       seqinfo->dobj.dump = true;
-                               }
-                               break;
-                       }
+                       seqinfo->interesting = true;
+                       seqinfo->dobj.dump = true;
                }
        }
-
-       destroyPQExpBuffer(query);
-
-       return tblinfo;
 }
 
 /*
@@ -4426,7 +4880,7 @@ getTables(int *numTables)
  * numInherits is set to the number of pairs read in
  */
 InhInfo *
-getInherits(int *numInherits)
+getInherits(Archive *fout, int *numInherits)
 {
        PGresult   *res;
        int                     ntups;
@@ -4438,14 +4892,13 @@ getInherits(int *numInherits)
        int                     i_inhparent;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        /* find all the inheritance information */
 
-       appendPQExpBuffer(query, "SELECT inhrelid, inhparent FROM pg_inherits");
+       appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -4477,7 +4930,7 @@ getInherits(int *numInherits)
  * does get entered into the DumpableObject tables.
  */
 void
-getIndexes(TableInfo tblinfo[], int numTables)
+getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 {
        int                     i,
                                j;
@@ -4492,6 +4945,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                i_indnkeys,
                                i_indkey,
                                i_indisclustered,
+                               i_indisreplident,
                                i_contype,
                                i_conname,
                                i_condeferrable,
@@ -4500,15 +4954,19 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                i_conoid,
                                i_condef,
                                i_tablespace,
-                               i_options;
+                               i_options,
+                               i_relpages;
        int                     ntups;
 
        for (i = 0; i < numTables; i++)
        {
                TableInfo  *tbinfo = &tblinfo[i];
 
-               /* Only plain tables have indexes */
-               if (tbinfo->relkind != RELKIND_RELATION || !tbinfo->hasindex)
+               /* Only plain tables and materialized views have indexes. */
+               if (tbinfo->relkind != RELKIND_RELATION &&
+                       tbinfo->relkind != RELKIND_MATVIEW)
+                       continue;
+               if (!tbinfo->hasindex)
                        continue;
 
                /* Ignore indexes of tables not to be dumped */
@@ -4520,7 +4978,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                          tbinfo->dobj.name);
 
                /* Make sure we are in proper schema so indexdef is right */
-               selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
                /*
                 * The point of the messy-looking outer join is to find a constraint
@@ -4534,14 +4992,50 @@ getIndexes(TableInfo tblinfo[], int numTables)
                 * is not.
                 */
                resetPQExpBuffer(query);
-               if (g_fout->remoteVersion >= 90000)
+               if (fout->remoteVersion >= 90400)
+               {
+                       /*
+                        * the test on indisready is necessary in 9.2, and harmless in
+                        * earlier/later versions
+                        */
+                       appendPQExpBuffer(query,
+                                                         "SELECT t.tableoid, t.oid, "
+                                                         "t.relname AS indexname, "
+                                        "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
+                                                         "t.relnatts AS indnkeys, "
+                                                         "i.indkey, i.indisclustered, "
+                                                         "i.indisreplident, t.relpages, "
+                                                         "c.contype, c.conname, "
+                                                         "c.condeferrable, c.condeferred, "
+                                                         "c.tableoid AS contableoid, "
+                                                         "c.oid AS conoid, "
+                                 "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, "
+                                                         "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, "
+                                                       "array_to_string(t.reloptions, ', ') AS options "
+                                                         "FROM pg_catalog.pg_index i "
+                                         "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
+                                                         "LEFT JOIN pg_catalog.pg_constraint c "
+                                                         "ON (i.indrelid = c.conrelid AND "
+                                                         "i.indexrelid = c.conindid AND "
+                                                         "c.contype IN ('p','u','x')) "
+                                                         "WHERE i.indrelid = '%u'::pg_catalog.oid "
+                                                         "AND i.indisvalid AND i.indisready "
+                                                         "ORDER BY indexname",
+                                                         tbinfo->dobj.catId.oid);
+               }
+               else if (fout->remoteVersion >= 90000)
                {
+                       /*
+                        * the test on indisready is necessary in 9.2, and harmless in
+                        * earlier/later versions
+                        */
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
                                                          "t.relname AS indexname, "
                                         "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, i.indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "c.contype, c.conname, "
                                                          "c.condeferrable, c.condeferred, "
                                                          "c.tableoid AS contableoid, "
@@ -4556,10 +5050,11 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "i.indexrelid = c.conindid AND "
                                                          "c.contype IN ('p','u','x')) "
                                                          "WHERE i.indrelid = '%u'::pg_catalog.oid "
+                                                         "AND i.indisvalid AND i.indisready "
                                                          "ORDER BY indexname",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 80200)
+               else if (fout->remoteVersion >= 80200)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
@@ -4567,6 +5062,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                         "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, i.indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "c.contype, c.conname, "
                                                          "c.condeferrable, c.condeferred, "
                                                          "c.tableoid AS contableoid, "
@@ -4584,10 +5080,11 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "ON (d.refclassid = c.tableoid "
                                                          "AND d.refobjid = c.oid) "
                                                          "WHERE i.indrelid = '%u'::pg_catalog.oid "
+                                                         "AND i.indisvalid "
                                                          "ORDER BY indexname",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 80000)
+               else if (fout->remoteVersion >= 80000)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
@@ -4595,6 +5092,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                         "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, i.indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "c.contype, c.conname, "
                                                          "c.condeferrable, c.condeferred, "
                                                          "c.tableoid AS contableoid, "
@@ -4615,7 +5113,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "ORDER BY indexname",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70300)
+               else if (fout->remoteVersion >= 70300)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
@@ -4623,6 +5121,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                         "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, i.indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "c.contype, c.conname, "
                                                          "c.condeferrable, c.condeferred, "
                                                          "c.tableoid AS contableoid, "
@@ -4643,7 +5142,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "ORDER BY indexname",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70100)
+               else if (fout->remoteVersion >= 70100)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT t.tableoid, t.oid, "
@@ -4651,6 +5150,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, false AS indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "CASE WHEN i.indisprimary THEN 'p'::char "
                                                          "ELSE '0'::char END AS contype, "
                                                          "t.relname AS conname, "
@@ -4677,6 +5177,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          "pg_get_indexdef(i.indexrelid) AS indexdef, "
                                                          "t.relnatts AS indnkeys, "
                                                          "i.indkey, false AS indisclustered, "
+                                                         "false AS indisreplident, t.relpages, "
                                                          "CASE WHEN i.indisprimary THEN 'p'::char "
                                                          "ELSE '0'::char END AS contype, "
                                                          "t.relname AS conname, "
@@ -4694,8 +5195,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
                                                          tbinfo->dobj.catId.oid);
                }
 
-               res = PQexec(g_conn, query->data);
-               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
                ntups = PQntuples(res);
 
@@ -4706,6 +5206,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                i_indnkeys = PQfnumber(res, "indnkeys");
                i_indkey = PQfnumber(res, "indkey");
                i_indisclustered = PQfnumber(res, "indisclustered");
+               i_indisreplident = PQfnumber(res, "indisreplident");
+               i_relpages = PQfnumber(res, "relpages");
                i_contype = PQfnumber(res, "contype");
                i_conname = PQfnumber(res, "conname");
                i_condeferrable = PQfnumber(res, "condeferrable");
@@ -4748,6 +5250,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
                        parseOidArray(PQgetvalue(res, j, i_indkey),
                                                  indxinfo[j].indkeys, INDEX_MAX_KEYS);
                        indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't');
+                       indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't');
+                       indxinfo[j].relpages = atoi(PQgetvalue(res, j, i_relpages));
                        contype = *(PQgetvalue(res, j, i_contype));
 
                        if (contype == 'p' || contype == 'u' || contype == 'x')
@@ -4808,7 +5312,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
  * while check constraints are processed in getTableAttrs().
  */
 void
-getConstraints(TableInfo tblinfo[], int numTables)
+getConstraints(Archive *fout, TableInfo tblinfo[], int numTables)
 {
        int                     i,
                                j;
@@ -4823,7 +5327,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
        int                     ntups;
 
        /* pg_constraint was created in 7.3, so nothing to do if older */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
                return;
 
        query = createPQExpBuffer();
@@ -4843,7 +5347,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
                 * select table schema to ensure constraint expr is qualified if
                 * needed
                 */
-               selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
                resetPQExpBuffer(query);
                appendPQExpBuffer(query,
@@ -4853,8 +5357,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                  "AND contype = 'f'",
                                                  tbinfo->dobj.catId.oid);
-               res = PQexec(g_conn, query->data);
-               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
                ntups = PQntuples(res);
 
@@ -4898,7 +5401,7 @@ getConstraints(TableInfo tblinfo[], int numTables)
  * Get info about constraints on a domain.
  */
 static void
-getDomainConstraints(TypeInfo *tyinfo)
+getDomainConstraints(Archive *fout, TypeInfo *tyinfo)
 {
        int                     i;
        ConstraintInfo *constrinfo;
@@ -4911,18 +5414,18 @@ getDomainConstraints(TypeInfo *tyinfo)
        int                     ntups;
 
        /* pg_constraint was created in 7.3, so nothing to do if older */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
                return;
 
        /*
         * select appropriate schema to ensure names in constraint are properly
         * qualified
         */
-       selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
 
        query = createPQExpBuffer();
 
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90100)
                appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                                                  "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
                                                  "convalidated "
@@ -4931,7 +5434,7 @@ getDomainConstraints(TypeInfo *tyinfo)
                                                  "ORDER BY conname",
                                                  tyinfo->dobj.catId.oid);
 
-       else if (g_fout->remoteVersion >= 70400)
+       else if (fout->remoteVersion >= 70400)
                appendPQExpBuffer(query, "SELECT tableoid, oid, conname, "
                                                  "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
                                                  "true as convalidated "
@@ -4948,8 +5451,7 @@ getDomainConstraints(TypeInfo *tyinfo)
                                                  "ORDER BY conname",
                                                  tyinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -4965,7 +5467,7 @@ getDomainConstraints(TypeInfo *tyinfo)
 
        for (i = 0; i < ntups; i++)
        {
-               bool    validated = PQgetvalue(res, i, 4)[0] == 't';
+               bool            validated = PQgetvalue(res, i, 4)[0] == 't';
 
                constrinfo[i].dobj.objType = DO_CONSTRAINT;
                constrinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
@@ -4987,7 +5489,7 @@ getDomainConstraints(TypeInfo *tyinfo)
 
                /*
                 * Make the domain depend on the constraint, ensuring it won't be
-                * output till any constraint dependencies are OK.  If the constraint
+                * output till any constraint dependencies are OK.      If the constraint
                 * has not been validated, it's going to be dumped after the domain
                 * anyway, so this doesn't matter.
                 */
@@ -5008,7 +5510,7 @@ getDomainConstraints(TypeInfo *tyinfo)
  * numRules is set to the number of rules read in
  */
 RuleInfo *
-getRules(int *numRules)
+getRules(Archive *fout, int *numRules)
 {
        PGresult   *res;
        int                     ntups;
@@ -5024,39 +5526,38 @@ getRules(int *numRules)
        int                     i_ev_enabled;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 80300)
        {
-               appendPQExpBuffer(query, "SELECT "
-                                                 "tableoid, oid, rulename, "
-                                                 "ev_class AS ruletable, ev_type, is_instead, "
-                                                 "ev_enabled "
-                                                 "FROM pg_rewrite "
-                                                 "ORDER BY oid");
+               appendPQExpBufferStr(query, "SELECT "
+                                                        "tableoid, oid, rulename, "
+                                                        "ev_class AS ruletable, ev_type, is_instead, "
+                                                        "ev_enabled "
+                                                        "FROM pg_rewrite "
+                                                        "ORDER BY oid");
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
-               appendPQExpBuffer(query, "SELECT "
-                                                 "tableoid, oid, rulename, "
-                                                 "ev_class AS ruletable, ev_type, is_instead, "
-                                                 "'O'::char AS ev_enabled "
-                                                 "FROM pg_rewrite "
-                                                 "ORDER BY oid");
+               appendPQExpBufferStr(query, "SELECT "
+                                                        "tableoid, oid, rulename, "
+                                                        "ev_class AS ruletable, ev_type, is_instead, "
+                                                        "'O'::char AS ev_enabled "
+                                                        "FROM pg_rewrite "
+                                                        "ORDER BY oid");
        }
        else
        {
-               appendPQExpBuffer(query, "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') AS tableoid, "
-                                                 "oid, rulename, "
-                                                 "ev_class AS ruletable, ev_type, is_instead, "
-                                                 "'O'::char AS ev_enabled "
-                                                 "FROM pg_rewrite "
-                                                 "ORDER BY oid");
+               appendPQExpBufferStr(query, "SELECT "
+                                                        "(SELECT oid FROM pg_class WHERE relname = 'pg_rewrite') AS tableoid, "
+                                                        "oid, rulename, "
+                                                        "ev_class AS ruletable, ev_type, is_instead, "
+                                                        "'O'::char AS ev_enabled "
+                                                        "FROM pg_rewrite "
+                                                        "ORDER BY oid");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -5084,12 +5585,8 @@ getRules(int *numRules)
                ruletableoid = atooid(PQgetvalue(res, i, i_ruletable));
                ruleinfo[i].ruletable = findTableByOid(ruletableoid);
                if (ruleinfo[i].ruletable == NULL)
-               {
-                       write_msg(NULL, "failed sanity check, parent table OID %u of pg_rewrite entry OID %u not found\n",
-                                         ruletableoid,
-                                         ruleinfo[i].dobj.catId.oid);
-                       exit_nicely();
-               }
+                       exit_horribly(NULL, "failed sanity check, parent table OID %u of pg_rewrite entry OID %u not found\n",
+                                                 ruletableoid, ruleinfo[i].dobj.catId.oid);
                ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace;
                ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump;
                ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type));
@@ -5098,12 +5595,14 @@ getRules(int *numRules)
                if (ruleinfo[i].ruletable)
                {
                        /*
-                        * If the table is a view, force its ON SELECT rule to be sorted
-                        * before the view itself --- this ensures that any dependencies
-                        * for the rule affect the table's positioning. Other rules are
-                        * forced to appear after their table.
+                        * If the table is a view or materialized view, force its ON
+                        * SELECT rule to be sorted before the view itself --- this
+                        * ensures that any dependencies for the rule affect the table's
+                        * positioning. Other rules are forced to appear after their
+                        * table.
                         */
-                       if (ruleinfo[i].ruletable->relkind == RELKIND_VIEW &&
+                       if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
+                                ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
                                ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
                        {
                                addObjectDependency(&ruleinfo[i].ruletable->dobj,
@@ -5120,6 +5619,16 @@ getRules(int *numRules)
                }
                else
                        ruleinfo[i].separate = true;
+
+               /*
+                * If we're forced to break a dependency loop by dumping a view as a
+                * table and separate _RETURN rule, we'll move the view's reloptions
+                * to the rule.  (This is necessary because tables and views have
+                * different valid reloptions, so we can't apply the options until the
+                * backend knows it's a view.)  Otherwise the rule's reloptions stay
+                * NULL.
+                */
+               ruleinfo[i].reloptions = NULL;
        }
 
        PQclear(res);
@@ -5137,7 +5646,7 @@ getRules(int *numRules)
  * does get entered into the DumpableObject tables.
  */
 void
-getTriggers(TableInfo tblinfo[], int numTables)
+getTriggers(Archive *fout, TableInfo tblinfo[], int numTables)
 {
        int                     i,
                                j;
@@ -5175,10 +5684,10 @@ getTriggers(TableInfo tblinfo[], int numTables)
                /*
                 * select table schema to ensure regproc name is qualified if needed
                 */
-               selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
                resetPQExpBuffer(query);
-               if (g_fout->remoteVersion >= 90000)
+               if (fout->remoteVersion >= 90000)
                {
                        /*
                         * NB: think not to use pretty=true in pg_get_triggerdef.  It
@@ -5195,7 +5704,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                                          "AND NOT tgisinternal",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 80300)
+               else if (fout->remoteVersion >= 80300)
                {
                        /*
                         * We ignore triggers that are tied to a foreign-key constraint
@@ -5212,7 +5721,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                                          "AND tgconstraint = 0",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70300)
+               else if (fout->remoteVersion >= 70300)
                {
                        /*
                         * We ignore triggers that are tied to a foreign-key constraint,
@@ -5235,7 +5744,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                                          "   WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70100)
+               else if (fout->remoteVersion >= 70100)
                {
                        appendPQExpBuffer(query,
                                                          "SELECT tgname, tgfoid::regproc AS tgfname, "
@@ -5263,8 +5772,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                                          "WHERE tgrelid = '%u'::oid",
                                                          tbinfo->dobj.catId.oid);
                }
-               res = PQexec(g_conn, query->data);
-               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
                ntups = PQntuples(res);
 
@@ -5331,12 +5839,10 @@ getTriggers(TableInfo tblinfo[], int numTables)
                                        if (OidIsValid(tginfo[j].tgconstrrelid))
                                        {
                                                if (PQgetisnull(res, j, i_tgconstrrelname))
-                                               {
-                                                       write_msg(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n",
-                                                                         tginfo[j].dobj.name, tbinfo->dobj.name,
-                                                                         tginfo[j].tgconstrrelid);
-                                                       exit_nicely();
-                                               }
+                                                       exit_horribly(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n",
+                                                                                 tginfo[j].dobj.name,
+                                                                                 tbinfo->dobj.name,
+                                                                                 tginfo[j].tgconstrrelid);
                                                tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname));
                                        }
                                        else
@@ -5357,6 +5863,89 @@ getTriggers(TableInfo tblinfo[], int numTables)
        destroyPQExpBuffer(query);
 }
 
+/*
+ * getEventTriggers
+ *       get information about event triggers
+ */
+EventTriggerInfo *
+getEventTriggers(Archive *fout, int *numEventTriggers)
+{
+       int                     i;
+       PQExpBuffer query;
+       PGresult   *res;
+       EventTriggerInfo *evtinfo;
+       int                     i_tableoid,
+                               i_oid,
+                               i_evtname,
+                               i_evtevent,
+                               i_evtowner,
+                               i_evttags,
+                               i_evtfname,
+                               i_evtenabled;
+       int                     ntups;
+
+       /* Before 9.3, there are no event triggers */
+       if (fout->remoteVersion < 90300)
+       {
+               *numEventTriggers = 0;
+               return NULL;
+       }
+
+       query = createPQExpBuffer();
+
+       /* Make sure we are in proper schema */
+       selectSourceSchema(fout, "pg_catalog");
+
+       appendPQExpBuffer(query,
+                                         "SELECT e.tableoid, e.oid, evtname, evtenabled, "
+                                         "evtevent, (%s evtowner) AS evtowner, "
+                                         "array_to_string(array("
+                                         "select quote_literal(x) "
+                                         " from unnest(evttags) as t(x)), ', ') as evttags, "
+                                         "e.evtfoid::regproc as evtfname "
+                                         "FROM pg_event_trigger e "
+                                         "ORDER BY e.oid",
+                                         username_subquery);
+
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+       ntups = PQntuples(res);
+
+       *numEventTriggers = ntups;
+
+       evtinfo = (EventTriggerInfo *) pg_malloc(ntups * sizeof(EventTriggerInfo));
+
+       i_tableoid = PQfnumber(res, "tableoid");
+       i_oid = PQfnumber(res, "oid");
+       i_evtname = PQfnumber(res, "evtname");
+       i_evtevent = PQfnumber(res, "evtevent");
+       i_evtowner = PQfnumber(res, "evtowner");
+       i_evttags = PQfnumber(res, "evttags");
+       i_evtfname = PQfnumber(res, "evtfname");
+       i_evtenabled = PQfnumber(res, "evtenabled");
+
+       for (i = 0; i < ntups; i++)
+       {
+               evtinfo[i].dobj.objType = DO_EVENT_TRIGGER;
+               evtinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+               evtinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+               AssignDumpId(&evtinfo[i].dobj);
+               evtinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_evtname));
+               evtinfo[i].evtname = pg_strdup(PQgetvalue(res, i, i_evtname));
+               evtinfo[i].evtevent = pg_strdup(PQgetvalue(res, i, i_evtevent));
+               evtinfo[i].evtowner = pg_strdup(PQgetvalue(res, i, i_evtowner));
+               evtinfo[i].evttags = pg_strdup(PQgetvalue(res, i, i_evttags));
+               evtinfo[i].evtfname = pg_strdup(PQgetvalue(res, i, i_evtfname));
+               evtinfo[i].evtenabled = *(PQgetvalue(res, i, i_evtenabled));
+       }
+
+       PQclear(res);
+
+       destroyPQExpBuffer(query);
+
+       return evtinfo;
+}
+
 /*
  * getProcLangs
  *       get basic information about every procedural language in the system
@@ -5367,7 +5956,7 @@ getTriggers(TableInfo tblinfo[], int numTables)
  * findFuncByOid().
  */
 ProcLangInfo *
-getProcLangs(int *numProcLangs)
+getProcLangs(Archive *fout, int *numProcLangs)
 {
        PGresult   *res;
        int                     ntups;
@@ -5385,9 +5974,9 @@ getProcLangs(int *numProcLangs)
        int                     i_lanowner;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 90000)
+       if (fout->remoteVersion >= 90000)
        {
                /* pg_language has a laninline column */
                appendPQExpBuffer(query, "SELECT tableoid, oid, "
@@ -5399,7 +5988,7 @@ getProcLangs(int *numProcLangs)
                                                  "ORDER BY oid",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 80300)
+       else if (fout->remoteVersion >= 80300)
        {
                /* pg_language has a lanowner column */
                appendPQExpBuffer(query, "SELECT tableoid, oid, "
@@ -5411,7 +6000,7 @@ getProcLangs(int *numProcLangs)
                                                  "ORDER BY oid",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 80100)
+       else if (fout->remoteVersion >= 80100)
        {
                /* Languages are owned by the bootstrap superuser, OID 10 */
                appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
@@ -5421,7 +6010,7 @@ getProcLangs(int *numProcLangs)
                                                  "ORDER BY oid",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70400)
+       else if (fout->remoteVersion >= 70400)
        {
                /* Languages are owned by the bootstrap superuser, sysid 1 */
                appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
@@ -5431,24 +6020,23 @@ getProcLangs(int *numProcLangs)
                                                  "ORDER BY oid",
                                                  username_subquery);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                /* No clear notion of an owner at all before 7.4 ... */
-               appendPQExpBuffer(query, "SELECT tableoid, oid, * FROM pg_language "
-                                                 "WHERE lanispl "
-                                                 "ORDER BY oid");
+               appendPQExpBufferStr(query, "SELECT tableoid, oid, * FROM pg_language "
+                                                        "WHERE lanispl "
+                                                        "ORDER BY oid");
        }
        else
        {
-               appendPQExpBuffer(query, "SELECT "
-                                                 "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, "
-                                                 "oid, * FROM pg_language "
-                                                 "WHERE lanispl "
-                                                 "ORDER BY oid");
+               appendPQExpBufferStr(query, "SELECT "
+                                                        "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, "
+                                                        "oid, * FROM pg_language "
+                                                        "WHERE lanispl "
+                                                        "ORDER BY oid");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -5494,7 +6082,7 @@ getProcLangs(int *numProcLangs)
                else
                        planginfo[i].lanowner = pg_strdup("");
 
-               if (g_fout->remoteVersion < 70300)
+               if (fout->remoteVersion < 70300)
                {
                        /*
                         * We need to make a dependency to ensure the function will be
@@ -5523,7 +6111,7 @@ getProcLangs(int *numProcLangs)
  * numCasts is set to the number of casts read in
  */
 CastInfo *
-getCasts(int *numCasts)
+getCasts(Archive *fout, int *numCasts)
 {
        PGresult   *res;
        int                     ntups;
@@ -5539,37 +6127,36 @@ getCasts(int *numCasts)
        int                     i_castmethod;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 80400)
        {
-               appendPQExpBuffer(query, "SELECT tableoid, oid, "
-                                                 "castsource, casttarget, castfunc, castcontext, "
-                                                 "castmethod "
-                                                 "FROM pg_cast ORDER BY 3,4");
+               appendPQExpBufferStr(query, "SELECT tableoid, oid, "
+                                                        "castsource, casttarget, castfunc, castcontext, "
+                                                        "castmethod "
+                                                        "FROM pg_cast ORDER BY 3,4");
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
-               appendPQExpBuffer(query, "SELECT tableoid, oid, "
-                                                 "castsource, casttarget, castfunc, castcontext, "
+               appendPQExpBufferStr(query, "SELECT tableoid, oid, "
+                                                        "castsource, casttarget, castfunc, castcontext, "
                                "CASE WHEN castfunc = 0 THEN 'b' ELSE 'f' END AS castmethod "
-                                                 "FROM pg_cast ORDER BY 3,4");
+                                                        "FROM pg_cast ORDER BY 3,4");
        }
        else
        {
-               appendPQExpBuffer(query, "SELECT 0 AS tableoid, p.oid, "
-                                                 "t1.oid AS castsource, t2.oid AS casttarget, "
-                                                 "p.oid AS castfunc, 'e' AS castcontext, "
-                                                 "'f' AS castmethod "
-                                                 "FROM pg_type t1, pg_type t2, pg_proc p "
-                                                 "WHERE p.pronargs = 1 AND "
-                                                 "p.proargtypes[0] = t1.oid AND "
-                                                 "p.prorettype = t2.oid AND p.proname = t2.typname "
-                                                 "ORDER BY 3,4");
+               appendPQExpBufferStr(query, "SELECT 0 AS tableoid, p.oid, "
+                                                        "t1.oid AS castsource, t2.oid AS casttarget, "
+                                                        "p.oid AS castfunc, 'e' AS castcontext, "
+                                                        "'f' AS castmethod "
+                                                        "FROM pg_type t1, pg_type t2, pg_proc p "
+                                                        "WHERE p.pronargs = 1 AND "
+                                                        "p.proargtypes[0] = t1.oid AND "
+                                                        "p.prorettype = t2.oid AND p.proname = t2.typname "
+                                                        "ORDER BY 3,4");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -5651,7 +6238,7 @@ getCasts(int *numCasts)
  *     modifies tblinfo
  */
 void
-getTableAttrs(TableInfo *tblinfo, int numTables)
+getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 {
        int                     i,
                                j;
@@ -5692,7 +6279,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                 * Make sure we are in proper schema for this table; this allows
                 * correct retrieval of formatted type names and default exprs
                 */
-               selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+               selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
                /* find all the user attributes and their types */
 
@@ -5709,7 +6296,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
                resetPQExpBuffer(q);
 
-               if (g_fout->remoteVersion >= 90200)
+               if (fout->remoteVersion >= 90200)
                {
                        /*
                         * attfdwoptions is new in 9.2.
@@ -5721,11 +6308,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
                                                "array_to_string(a.attoptions, ', ') AS attoptions, "
                                                          "CASE WHEN a.attcollation <> t.typcollation "
-                                                       "THEN a.attcollation ELSE 0 END AS attcollation, "
+                                                  "THEN a.attcollation ELSE 0 END AS attcollation, "
                                                          "pg_catalog.array_to_string(ARRAY("
                                                          "SELECT pg_catalog.quote_ident(option_name) || "
                                                          "' ' || pg_catalog.quote_literal(option_value) "
-                                                         "FROM pg_catalog.pg_options_to_table(attfdwoptions)"
+                                               "FROM pg_catalog.pg_options_to_table(attfdwoptions) "
+                                                         "ORDER BY option_name"
                                                          "), E',\n    ') AS attfdwoptions "
                         "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
                                                          "ON a.atttypid = t.oid "
@@ -5734,7 +6322,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          "ORDER BY a.attrelid, a.attnum",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 90100)
+               else if (fout->remoteVersion >= 90100)
                {
                        /*
                         * attcollation is new in 9.1.  Since we only want to dump COLLATE
@@ -5749,7 +6337,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                  "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, "
                                                "array_to_string(a.attoptions, ', ') AS attoptions, "
                                                          "CASE WHEN a.attcollation <> t.typcollation "
-                                                       "THEN a.attcollation ELSE 0 END AS attcollation, "
+                                                  "THEN a.attcollation ELSE 0 END AS attcollation, "
                                                          "NULL AS attfdwoptions "
                         "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t "
                                                          "ON a.atttypid = t.oid "
@@ -5758,7 +6346,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          "ORDER BY a.attrelid, a.attnum",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 90000)
+               else if (fout->remoteVersion >= 90000)
                {
                        /* attoptions is new in 9.0 */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
@@ -5776,7 +6364,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          "ORDER BY a.attrelid, a.attnum",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70300)
+               else if (fout->remoteVersion >= 70300)
                {
                        /* need left join here to not fail on dropped columns ... */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
@@ -5793,18 +6381,21 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          "ORDER BY a.attrelid, a.attnum",
                                                          tbinfo->dobj.catId.oid);
                }
-               else if (g_fout->remoteVersion >= 70100)
+               else if (fout->remoteVersion >= 70100)
                {
                        /*
                         * attstattarget doesn't exist in 7.1.  It does exist in 7.2, but
                         * we don't dump it because we can't tell whether it's been
                         * explicitly set or was just a default.
+                        *
+                        * attislocal doesn't exist before 7.3, either; in older databases
+                        * we assume it's TRUE, else we'd fail to dump non-inherited atts.
                         */
                        appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, "
                                                          "-1 AS attstattarget, a.attstorage, "
                                                          "t.typstorage, a.attnotnull, a.atthasdef, "
                                                          "false AS attisdropped, a.attlen, "
-                                                         "a.attalign, false AS attislocal, "
+                                                         "a.attalign, true AS attislocal, "
                                                          "format_type(t.oid,a.atttypmod) AS atttypname, "
                                                          "'' AS attoptions, 0 AS attcollation, "
                                                          "NULL AS attfdwoptions "
@@ -5823,7 +6414,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          "attstorage, attstorage AS typstorage, "
                                                          "attnotnull, atthasdef, false AS attisdropped, "
                                                          "attlen, attalign, "
-                                                         "false AS attislocal, "
+                                                         "true AS attislocal, "
                                                          "(SELECT typname FROM pg_type WHERE oid = atttypid) AS atttypname, "
                                                          "'' AS attoptions, 0 AS attcollation, "
                                                          "NULL AS attfdwoptions "
@@ -5834,8 +6425,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                          tbinfo->dobj.catId.oid);
                }
 
-               res = PQexec(g_conn, q->data);
-               check_sql_result(res, g_conn, q->data, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
 
                ntups = PQntuples(res);
 
@@ -5867,24 +6457,20 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int));
                tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char));
                tbinfo->attislocal = (bool *) pg_malloc(ntups * sizeof(bool));
-               tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
-               tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
                tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *));
                tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid));
                tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *));
-               tbinfo->inhAttrs = (bool *) pg_malloc(ntups * sizeof(bool));
-               tbinfo->inhAttrDef = (bool *) pg_malloc(ntups * sizeof(bool));
+               tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool));
                tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool));
+               tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *));
                hasdefaults = false;
 
                for (j = 0; j < ntups; j++)
                {
                        if (j + 1 != atoi(PQgetvalue(res, j, i_attnum)))
-                       {
-                               write_msg(NULL, "invalid column numbering in table \"%s\"\n",
-                                                 tbinfo->dobj.name);
-                               exit_nicely();
-                       }
+                               exit_horribly(NULL,
+                                                         "invalid column numbering in table \"%s\"\n",
+                                                         tbinfo->dobj.name);
                        tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname));
                        tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname));
                        tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));
@@ -5903,8 +6489,6 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        if (PQgetvalue(res, j, i_atthasdef)[0] == 't')
                                hasdefaults = true;
                        /* these flags will be set in flagInhAttrs() */
-                       tbinfo->inhAttrs[j] = false;
-                       tbinfo->inhAttrDef[j] = false;
                        tbinfo->inhNotNull[j] = false;
                }
 
@@ -5923,7 +6507,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                  tbinfo->dobj.name);
 
                        resetPQExpBuffer(q);
-                       if (g_fout->remoteVersion >= 70300)
+                       if (fout->remoteVersion >= 70300)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, adnum, "
                                                   "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc "
@@ -5931,7 +6515,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                                  "WHERE adrelid = '%u'::pg_catalog.oid",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70200)
+                       else if (fout->remoteVersion >= 70200)
                        {
                                /* 7.2 did not have OIDs in pg_attrdef */
                                appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, adnum, "
@@ -5940,7 +6524,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                                  "WHERE adrelid = '%u'::oid",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70100)
+                       else if (fout->remoteVersion >= 70100)
                        {
                                /* no pg_get_expr, so must rely on adsrc */
                                appendPQExpBuffer(q, "SELECT tableoid, oid, adnum, adsrc "
@@ -5958,8 +6542,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                                  "WHERE adrelid = '%u'::oid",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       res = PQexec(g_conn, q->data);
-                       check_sql_result(res, g_conn, q->data, PGRES_TUPLES_OK);
+                       res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
 
                        numDefaults = PQntuples(res);
                        attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
@@ -5968,12 +6551,26 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                        {
                                int                     adnum;
 
+                               adnum = atoi(PQgetvalue(res, j, 2));
+
+                               if (adnum <= 0 || adnum > ntups)
+                                       exit_horribly(NULL,
+                                                                 "invalid adnum value %d for table \"%s\"\n",
+                                                                 adnum, tbinfo->dobj.name);
+
+                               /*
+                                * dropped columns shouldn't have defaults, but just in case,
+                                * ignore 'em
+                                */
+                               if (tbinfo->attisdropped[adnum - 1])
+                                       continue;
+
                                attrdefs[j].dobj.objType = DO_ATTRDEF;
                                attrdefs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
                                attrdefs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
                                AssignDumpId(&attrdefs[j].dobj);
                                attrdefs[j].adtable = tbinfo;
-                               attrdefs[j].adnum = adnum = atoi(PQgetvalue(res, j, 2));
+                               attrdefs[j].adnum = adnum;
                                attrdefs[j].adef_expr = pg_strdup(PQgetvalue(res, j, 3));
 
                                attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name);
@@ -5984,9 +6581,8 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                /*
                                 * Defaults on a VIEW must always be dumped as separate ALTER
                                 * TABLE commands.      Defaults on regular tables are dumped as
-                                * part of the CREATE TABLE if possible.  To check if it's
-                                * safe, we mark the default as needing to appear before the
-                                * CREATE.
+                                * part of the CREATE TABLE if possible, which it won't be if
+                                * the column is not going to be emitted explicitly.
                                 */
                                if (tbinfo->relkind == RELKIND_VIEW)
                                {
@@ -5995,19 +6591,28 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                        addObjectDependency(&attrdefs[j].dobj,
                                                                                tbinfo->dobj.dumpId);
                                }
+                               else if (!shouldPrintColumn(tbinfo, adnum - 1))
+                               {
+                                       /* column will be suppressed, print default separately */
+                                       attrdefs[j].separate = true;
+                                       /* needed in case pre-7.3 DB: */
+                                       addObjectDependency(&attrdefs[j].dobj,
+                                                                               tbinfo->dobj.dumpId);
+                               }
                                else
                                {
                                        attrdefs[j].separate = false;
+
+                                       /*
+                                        * Mark the default as needing to appear before the table,
+                                        * so that any dependencies it has must be emitted before
+                                        * the CREATE TABLE.  If this is not possible, we'll
+                                        * change to "separate" mode while sorting dependencies.
+                                        */
                                        addObjectDependency(&tbinfo->dobj,
                                                                                attrdefs[j].dobj.dumpId);
                                }
 
-                               if (adnum <= 0 || adnum > ntups)
-                               {
-                                       write_msg(NULL, "invalid adnum value %d for table \"%s\"\n",
-                                                         adnum, tbinfo->dobj.name);
-                                       exit_nicely();
-                               }
                                tbinfo->attrdefs[adnum - 1] = &attrdefs[j];
                        }
                        PQclear(res);
@@ -6026,79 +6631,74 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                  tbinfo->dobj.name);
 
                        resetPQExpBuffer(q);
-                       if (g_fout->remoteVersion >= 90200)
+                       if (fout->remoteVersion >= 90200)
                        {
                                /*
-                                * conisonly and convalidated are new in 9.2 (actually, the latter
-                                * is there in 9.1, but it wasn't ever false for check constraints
-                                * until 9.2).
+                                * convalidated is new in 9.2 (actually, it is there in 9.1,
+                                * but it wasn't ever false for check constraints until 9.2).
                                 */
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                                                   "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                                                 "conislocal, convalidated, conisonly "
+                                                                 "conislocal, convalidated "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
                                                                  "ORDER BY conname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 80400)
+                       else if (fout->remoteVersion >= 80400)
                        {
+                               /* conislocal is new in 8.4 */
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                                                   "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                                                 "conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "conislocal, true AS convalidated "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
                                                                  "ORDER BY conname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70400)
+                       else if (fout->remoteVersion >= 70400)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                                                   "pg_catalog.pg_get_constraintdef(oid) AS consrc, "
-                                                                 "true AS conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "true AS conislocal, true AS convalidated "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
                                                                  "ORDER BY conname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70300)
+                       else if (fout->remoteVersion >= 70300)
                        {
                                /* no pg_get_constraintdef, must use consrc */
                                appendPQExpBuffer(q, "SELECT tableoid, oid, conname, "
                                                                  "'CHECK (' || consrc || ')' AS consrc, "
-                                                                 "true AS conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "true AS conislocal, true AS convalidated "
                                                                  "FROM pg_catalog.pg_constraint "
                                                                  "WHERE conrelid = '%u'::pg_catalog.oid "
                                                                  "   AND contype = 'c' "
                                                                  "ORDER BY conname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70200)
+                       else if (fout->remoteVersion >= 70200)
                        {
                                /* 7.2 did not have OIDs in pg_relcheck */
                                appendPQExpBuffer(q, "SELECT tableoid, 0 AS oid, "
                                                                  "rcname AS conname, "
                                                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                                                 "true AS conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "true AS conislocal, true AS convalidated "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       else if (g_fout->remoteVersion >= 70100)
+                       else if (fout->remoteVersion >= 70100)
                        {
                                appendPQExpBuffer(q, "SELECT tableoid, oid, "
                                                                  "rcname AS conname, "
                                                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                                                 "true AS conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "true AS conislocal, true AS convalidated "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
@@ -6111,15 +6711,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                                  "(SELECT oid FROM pg_class WHERE relname = 'pg_relcheck') AS tableoid, "
                                                                  "oid, rcname AS conname, "
                                                                  "'CHECK (' || rcsrc || ')' AS consrc, "
-                                                                 "true AS conislocal, true AS convalidated, "
-                                                                 "false as conisonly "
+                                                                 "true AS conislocal, true AS convalidated "
                                                                  "FROM pg_relcheck "
                                                                  "WHERE rcrelid = '%u'::oid "
                                                                  "ORDER BY rcname",
                                                                  tbinfo->dobj.catId.oid);
                        }
-                       res = PQexec(g_conn, q->data);
-                       check_sql_result(res, g_conn, q->data, PGRES_TUPLES_OK);
+                       res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);
 
                        numConstrs = PQntuples(res);
                        if (numConstrs != tbinfo->ncheck)
@@ -6129,7 +6727,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                                                                 tbinfo->ncheck),
                                                  tbinfo->ncheck, tbinfo->dobj.name, numConstrs);
                                write_msg(NULL, "(The system catalogs might be corrupted.)\n");
-                               exit_nicely();
+                               exit_nicely(1);
                        }
 
                        constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo));
@@ -6137,8 +6735,7 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
 
                        for (j = 0; j < numConstrs; j++)
                        {
-                               bool    validated = PQgetvalue(res, j, 5)[0] == 't';
-                               bool    isonly = PQgetvalue(res, j, 6)[0] == 't';
+                               bool            validated = PQgetvalue(res, j, 5)[0] == 't';
 
                                constrs[j].dobj.objType = DO_CONSTRAINT;
                                constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
@@ -6155,14 +6752,13 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                constrs[j].condeferrable = false;
                                constrs[j].condeferred = false;
                                constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't');
-                               constrs[j].conisonly = isonly;
+
                                /*
                                 * An unvalidated constraint needs to be dumped separately, so
                                 * that potentially-violating existing data is loaded before
-                                * the constraint.  An ONLY constraint needs to be dumped
-                                * separately too.
+                                * the constraint.
                                 */
-                               constrs[j].separate = !validated || isonly;
+                               constrs[j].separate = !validated;
 
                                constrs[j].dobj.dump = tbinfo->dobj.dump;
 
@@ -6170,10 +6766,10 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
                                 * Mark the constraint as needing to appear before the table
                                 * --- this is so that any other dependencies of the
                                 * constraint will be emitted before we try to create the
-                                * table.  If the constraint is to be dumped separately, it will be
-                                * dumped after data is loaded anyway, so don't do it.  (There's
-                                * an automatic dependency in the opposite direction anyway, so
-                                * don't need to add one manually here.)
+                                * table.  If the constraint is to be dumped separately, it
+                                * will be dumped after data is loaded anyway, so don't do it.
+                                * (There's an automatic dependency in the opposite direction
+                                * anyway, so don't need to add one manually here.)
                                 */
                                if (!constrs[j].separate)
                                        addObjectDependency(&tbinfo->dobj,
@@ -6192,6 +6788,28 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
        destroyPQExpBuffer(q);
 }
 
+/*
+ * Test whether a column should be printed as part of table's CREATE TABLE.
+ * Column number is zero-based.
+ *
+ * Normally this is always true, but it's false for dropped columns, as well
+ * as those that were inherited without any local definition.  (If we print
+ * such a column it will mistakenly get pg_attribute.attislocal set to true.)
+ * However, in binary_upgrade mode, we must print all such columns anyway and
+ * fix the attislocal/attisdropped state later, so as to keep control of the
+ * physical column order.
+ *
+ * This function exists because there are scattered nonobvious places that
+ * must be kept in sync with this decision.
+ */
+bool
+shouldPrintColumn(TableInfo *tbinfo, int colno)
+{
+       if (binary_upgrade)
+               return true;
+       return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]);
+}
+
 
 /*
  * getTSParsers:
@@ -6201,12 +6819,12 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
  *     numTSParsers is set to the number of parsers read in
  */
 TSParserInfo *
-getTSParsers(int *numTSParsers)
+getTSParsers(Archive *fout, int *numTSParsers)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        TSParserInfo *prsinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6219,27 +6837,28 @@ getTSParsers(int *numTSParsers)
        int                     i_prslextype;
 
        /* Before 8.3, there is no built-in text search support */
-       if (g_fout->remoteVersion < 80300)
+       if (fout->remoteVersion < 80300)
        {
                *numTSParsers = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /*
         * find all text search objects, including builtin ones; we filter out
         * system-defined objects at dump-out time.
         */
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       appendPQExpBuffer(query, "SELECT tableoid, oid, prsname, prsnamespace, "
-                                         "prsstart::oid, prstoken::oid, "
-                                         "prsend::oid, prsheadline::oid, prslextype::oid "
-                                         "FROM pg_ts_parser");
+       appendPQExpBufferStr(query, "SELECT tableoid, oid, prsname, prsnamespace, "
+                                                "prsstart::oid, prstoken::oid, "
+                                                "prsend::oid, prsheadline::oid, prslextype::oid "
+                                                "FROM pg_ts_parser");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numTSParsers = ntups;
@@ -6263,8 +6882,10 @@ getTSParsers(int *numTSParsers)
                prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&prsinfo[i].dobj);
                prsinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_prsname));
-               prsinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)),
-                                                                                                 prsinfo[i].dobj.catId.oid);
+               prsinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_prsnamespace)),
+                                                 prsinfo[i].dobj.catId.oid);
                prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
                prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
                prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
@@ -6290,12 +6911,12 @@ getTSParsers(int *numTSParsers)
  *     numTSDicts is set to the number of dictionaries read in
  */
 TSDictInfo *
-getTSDictionaries(int *numTSDicts)
+getTSDictionaries(Archive *fout, int *numTSDicts)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        TSDictInfo *dictinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6306,14 +6927,16 @@ getTSDictionaries(int *numTSDicts)
        int                     i_dictinitoption;
 
        /* Before 8.3, there is no built-in text search support */
-       if (g_fout->remoteVersion < 80300)
+       if (fout->remoteVersion < 80300)
        {
                *numTSDicts = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, dictname, "
                                          "dictnamespace, (%s dictowner) AS rolname, "
@@ -6321,8 +6944,7 @@ getTSDictionaries(int *numTSDicts)
                                          "FROM pg_ts_dict",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numTSDicts = ntups;
@@ -6344,8 +6966,10 @@ getTSDictionaries(int *numTSDicts)
                dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&dictinfo[i].dobj);
                dictinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_dictname));
-               dictinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)),
-                                                                                                dictinfo[i].dobj.catId.oid);
+               dictinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_dictnamespace)),
+                                                 dictinfo[i].dobj.catId.oid);
                dictinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
                if (PQgetisnull(res, i, i_dictinitoption))
@@ -6372,12 +6996,12 @@ getTSDictionaries(int *numTSDicts)
  *     numTSTemplates is set to the number of templates read in
  */
 TSTemplateInfo *
-getTSTemplates(int *numTSTemplates)
+getTSTemplates(Archive *fout, int *numTSTemplates)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        TSTemplateInfo *tmplinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6387,21 +7011,22 @@ getTSTemplates(int *numTSTemplates)
        int                     i_tmpllexize;
 
        /* Before 8.3, there is no built-in text search support */
-       if (g_fout->remoteVersion < 80300)
+       if (fout->remoteVersion < 80300)
        {
                *numTSTemplates = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       appendPQExpBuffer(query, "SELECT tableoid, oid, tmplname, "
-                                         "tmplnamespace, tmplinit::oid, tmpllexize::oid "
-                                         "FROM pg_ts_template");
+       appendPQExpBufferStr(query, "SELECT tableoid, oid, tmplname, "
+                                                "tmplnamespace, tmplinit::oid, tmpllexize::oid "
+                                                "FROM pg_ts_template");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numTSTemplates = ntups;
@@ -6422,8 +7047,10 @@ getTSTemplates(int *numTSTemplates)
                tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&tmplinfo[i].dobj);
                tmplinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_tmplname));
-               tmplinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)),
-                                                                                                tmplinfo[i].dobj.catId.oid);
+               tmplinfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_tmplnamespace)),
+                                                 tmplinfo[i].dobj.catId.oid);
                tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
                tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
 
@@ -6446,12 +7073,12 @@ getTSTemplates(int *numTSTemplates)
  *     numTSConfigs is set to the number of configurations read in
  */
 TSConfigInfo *
-getTSConfigurations(int *numTSConfigs)
+getTSConfigurations(Archive *fout, int *numTSConfigs)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        TSConfigInfo *cfginfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6461,22 +7088,23 @@ getTSConfigurations(int *numTSConfigs)
        int                     i_cfgparser;
 
        /* Before 8.3, there is no built-in text search support */
-       if (g_fout->remoteVersion < 80300)
+       if (fout->remoteVersion < 80300)
        {
                *numTSConfigs = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, cfgname, "
                                          "cfgnamespace, (%s cfgowner) AS rolname, cfgparser "
                                          "FROM pg_ts_config",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numTSConfigs = ntups;
@@ -6497,8 +7125,10 @@ getTSConfigurations(int *numTSConfigs)
                cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
                AssignDumpId(&cfginfo[i].dobj);
                cfginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_cfgname));
-               cfginfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)),
-                                                                                                 cfginfo[i].dobj.catId.oid);
+               cfginfo[i].dobj.namespace =
+                       findNamespace(fout,
+                                                 atooid(PQgetvalue(res, i, i_cfgnamespace)),
+                                                 cfginfo[i].dobj.catId.oid);
                cfginfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
                cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
 
@@ -6521,12 +7151,12 @@ getTSConfigurations(int *numTSConfigs)
  *     numForeignDataWrappers is set to the number of fdws read in
  */
 FdwInfo *
-getForeignDataWrappers(int *numForeignDataWrappers)
+getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        FdwInfo    *fdwinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6538,16 +7168,18 @@ getForeignDataWrappers(int *numForeignDataWrappers)
        int                     i_fdwoptions;
 
        /* Before 8.4, there are no foreign-data wrappers */
-       if (g_fout->remoteVersion < 80400)
+       if (fout->remoteVersion < 80400)
        {
                *numForeignDataWrappers = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90100)
        {
                appendPQExpBuffer(query, "SELECT tableoid, oid, fdwname, "
                                                  "(%s fdwowner) AS rolname, "
@@ -6556,7 +7188,8 @@ getForeignDataWrappers(int *numForeignDataWrappers)
                                                  "array_to_string(ARRAY("
                                                  "SELECT quote_ident(option_name) || ' ' || "
                                                  "quote_literal(option_value) "
-                                                 "FROM pg_options_to_table(fdwoptions)"
+                                                 "FROM pg_options_to_table(fdwoptions) "
+                                                 "ORDER BY option_name"
                                                  "), E',\n    ') AS fdwoptions "
                                                  "FROM pg_foreign_data_wrapper",
                                                  username_subquery);
@@ -6570,14 +7203,14 @@ getForeignDataWrappers(int *numForeignDataWrappers)
                                                  "array_to_string(ARRAY("
                                                  "SELECT quote_ident(option_name) || ' ' || "
                                                  "quote_literal(option_value) "
-                                                 "FROM pg_options_to_table(fdwoptions)"
+                                                 "FROM pg_options_to_table(fdwoptions) "
+                                                 "ORDER BY option_name"
                                                  "), E',\n    ') AS fdwoptions "
                                                  "FROM pg_foreign_data_wrapper",
                                                  username_subquery);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numForeignDataWrappers = ntups;
@@ -6626,12 +7259,12 @@ getForeignDataWrappers(int *numForeignDataWrappers)
  *     numForeignServers is set to the number of servers read in
  */
 ForeignServerInfo *
-getForeignServers(int *numForeignServers)
+getForeignServers(Archive *fout, int *numForeignServers)
 {
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        ForeignServerInfo *srvinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6644,14 +7277,16 @@ getForeignServers(int *numForeignServers)
        int                     i_srvoptions;
 
        /* Before 8.4, there are no foreign servers */
-       if (g_fout->remoteVersion < 80400)
+       if (fout->remoteVersion < 80400)
        {
                *numForeignServers = 0;
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT tableoid, oid, srvname, "
                                          "(%s srvowner) AS rolname, "
@@ -6659,13 +7294,13 @@ getForeignServers(int *numForeignServers)
                                          "array_to_string(ARRAY("
                                          "SELECT quote_ident(option_name) || ' ' || "
                                          "quote_literal(option_value) "
-                                         "FROM pg_options_to_table(srvoptions)"
+                                         "FROM pg_options_to_table(srvoptions) "
+                                         "ORDER BY option_name"
                                          "), E',\n    ') AS srvoptions "
                                          "FROM pg_foreign_server",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numForeignServers = ntups;
@@ -6716,7 +7351,7 @@ getForeignServers(int *numForeignServers)
  *     numDefaultACLs is set to the number of ACLs read in
  */
 DefaultACLInfo *
-getDefaultACLs(int *numDefaultACLs)
+getDefaultACLs(Archive *fout, int *numDefaultACLs)
 {
        DefaultACLInfo *daclinfo;
        PQExpBuffer query;
@@ -6730,7 +7365,7 @@ getDefaultACLs(int *numDefaultACLs)
        int                     i,
                                ntups;
 
-       if (g_fout->remoteVersion < 90000)
+       if (fout->remoteVersion < 90000)
        {
                *numDefaultACLs = 0;
                return NULL;
@@ -6739,7 +7374,7 @@ getDefaultACLs(int *numDefaultACLs)
        query = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query, "SELECT oid, tableoid, "
                                          "(%s defaclrole) AS defaclrole, "
@@ -6749,8 +7384,7 @@ getDefaultACLs(int *numDefaultACLs)
                                          "FROM pg_default_acl",
                                          username_subquery);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        *numDefaultACLs = ntups;
@@ -6776,7 +7410,7 @@ getDefaultACLs(int *numDefaultACLs)
                daclinfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_defaclobjtype));
 
                if (nspid != InvalidOid)
-                       daclinfo[i].dobj.namespace = findNamespace(nspid,
+                       daclinfo[i].dobj.namespace = findNamespace(fout, nspid,
                                                                                                 daclinfo[i].dobj.catId.oid);
                else
                        daclinfo[i].dobj.namespace = NULL;
@@ -6854,7 +7488,7 @@ dumpComment(Archive *fout, const char *target,
 
                appendPQExpBuffer(query, "COMMENT ON %s IS ", target);
                appendStringLiteralAH(query, comments->descr, fout);
-               appendPQExpBuffer(query, ";\n");
+               appendPQExpBufferStr(query, ";\n");
 
                /*
                 * We mark comments as SECTION_NONE because they really belong in the
@@ -6918,7 +7552,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
                        appendStringLiteralAH(query, descr, fout);
-                       appendPQExpBuffer(query, ";\n");
+                       appendPQExpBufferStr(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 target->data,
@@ -6934,13 +7568,12 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
                        resetPQExpBuffer(target);
                        appendPQExpBuffer(target, "COLUMN %s.",
                                                          fmtId(tbinfo->dobj.name));
-                       appendPQExpBuffer(target, "%s",
-                                                         fmtId(tbinfo->attnames[objsubid - 1]));
+                       appendPQExpBufferStr(target, fmtId(tbinfo->attnames[objsubid - 1]));
 
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
                        appendStringLiteralAH(query, descr, fout);
-                       appendPQExpBuffer(query, ";\n");
+                       appendPQExpBufferStr(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 target->data,
@@ -7081,26 +7714,25 @@ collectComments(Archive *fout, CommentItem **items)
 
        if (fout->remoteVersion >= 70300)
        {
-               appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
-                                                 "FROM pg_catalog.pg_description "
-                                                 "ORDER BY classoid, objoid, objsubid");
+               appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
+                                                        "FROM pg_catalog.pg_description "
+                                                        "ORDER BY classoid, objoid, objsubid");
        }
        else if (fout->remoteVersion >= 70200)
        {
-               appendPQExpBuffer(query, "SELECT description, classoid, objoid, objsubid "
-                                                 "FROM pg_description "
-                                                 "ORDER BY classoid, objoid, objsubid");
+               appendPQExpBufferStr(query, "SELECT description, classoid, objoid, objsubid "
+                                                        "FROM pg_description "
+                                                        "ORDER BY classoid, objoid, objsubid");
        }
        else
        {
                /* Note: this will fail to find attribute comments in pre-7.2... */
-               appendPQExpBuffer(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid "
-                                                 "FROM pg_description "
-                                                 "ORDER BY objoid");
+               appendPQExpBufferStr(query, "SELECT description, 0 AS classoid, objoid, 0 AS objsubid "
+                                                        "FROM pg_description "
+                                                        "ORDER BY objoid");
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        /* Construct lookup table containing OIDs in numeric form */
 
@@ -7137,28 +7769,6 @@ collectComments(Archive *fout, CommentItem **items)
 static void
 dumpDumpableObject(Archive *fout, DumpableObject *dobj)
 {
-
-       bool skip = false;
-
-       switch (dobj->objType)
-       {
-               case DO_INDEX:
-               case DO_TRIGGER:
-               case DO_CONSTRAINT:
-               case DO_FK_CONSTRAINT:
-               case DO_RULE:
-                       skip = !(dumpSections & DUMP_POST_DATA);
-                       break;
-               case DO_TABLE_DATA:
-                       skip = !(dumpSections & DUMP_DATA);
-                       break;
-               default:
-                       skip = !(dumpSections & DUMP_PRE_DATA);
-       }
-
-       if (skip)
-               return;
-
        switch (dobj->objType)
        {
                case DO_NAMESPACE:
@@ -7203,12 +7813,18 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                case DO_INDEX:
                        dumpIndex(fout, (IndxInfo *) dobj);
                        break;
+               case DO_REFRESH_MATVIEW:
+                       refreshMatViewData(fout, (TableDataInfo *) dobj);
+                       break;
                case DO_RULE:
                        dumpRule(fout, (RuleInfo *) dobj);
                        break;
                case DO_TRIGGER:
                        dumpTrigger(fout, (TriggerInfo *) dobj);
                        break;
+               case DO_EVENT_TRIGGER:
+                       dumpEventTrigger(fout, (EventTriggerInfo *) dobj);
+                       break;
                case DO_CONSTRAINT:
                        dumpConstraint(fout, (ConstraintInfo *) dobj);
                        break;
@@ -7222,7 +7838,10 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                        dumpCast(fout, (CastInfo *) dobj);
                        break;
                case DO_TABLE_DATA:
-                       dumpTableData(fout, (TableDataInfo *) dobj);
+                       if (((TableDataInfo *) dobj)->tdtable->relkind == RELKIND_SEQUENCE)
+                               dumpSequenceData(fout, (TableDataInfo *) dobj);
+                       else
+                               dumpTableData(fout, (TableDataInfo *) dobj);
                        break;
                case DO_DUMMY_TYPE:
                        /* table rowtypes and array types are never dumped separately */
@@ -7256,9 +7875,13 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
                                                 dobj->name, NULL, NULL, "",
                                                 false, "BLOBS", SECTION_DATA,
                                                 "", "", NULL,
-                                                dobj->dependencies, dobj->nDeps,
+                                                NULL, 0,
                                                 dumpBlobs, NULL);
                        break;
+               case DO_PRE_DATA_BOUNDARY:
+               case DO_POST_DATA_BOUNDARY:
+                       /* never dumped, nothing to do */
+                       break;
        }
 }
 
@@ -7303,7 +7926,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
                                 nspinfo->rolname,
                                 false, "SCHEMA", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                nspinfo->dobj.dependencies, nspinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Schema Comments and Security Labels */
@@ -7369,16 +7992,26 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                int                     i;
                int                     n;
 
-               appendPQExpBuffer(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
-               appendPQExpBuffer(q,
+               appendPQExpBufferStr(q, "-- For binary upgrade, create an empty extension and insert objects into it\n");
+
+               /*
+                * We unconditionally create the extension, so we must drop it if it
+                * exists.      This could happen if the user deleted 'plpgsql' and then
+                * readded it, causing its oid to be greater than FirstNormalObjectId.
+                * The FirstNormalObjectId test was kept to avoid repeatedly dropping
+                * and recreating extensions like 'plpgsql'.
+                */
+               appendPQExpBuffer(q, "DROP EXTENSION IF EXISTS %s;\n", qextname);
+
+               appendPQExpBufferStr(q,
                                                  "SELECT binary_upgrade.create_empty_extension(");
                appendStringLiteralAH(q, extinfo->dobj.name, fout);
-               appendPQExpBuffer(q, ", ");
+               appendPQExpBufferStr(q, ", ");
                appendStringLiteralAH(q, extinfo->namespace, fout);
-               appendPQExpBuffer(q, ", ");
+               appendPQExpBufferStr(q, ", ");
                appendPQExpBuffer(q, "%s, ", extinfo->relocatable ? "true" : "false");
                appendStringLiteralAH(q, extinfo->extversion, fout);
-               appendPQExpBuffer(q, ", ");
+               appendPQExpBufferStr(q, ", ");
 
                /*
                 * Note that we're pushing extconfig (an OID array) back into
@@ -7388,14 +8021,14 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                if (strlen(extinfo->extconfig) > 2)
                        appendStringLiteralAH(q, extinfo->extconfig, fout);
                else
-                       appendPQExpBuffer(q, "NULL");
-               appendPQExpBuffer(q, ", ");
+                       appendPQExpBufferStr(q, "NULL");
+               appendPQExpBufferStr(q, ", ");
                if (strlen(extinfo->extcondition) > 2)
                        appendStringLiteralAH(q, extinfo->extcondition, fout);
                else
-                       appendPQExpBuffer(q, "NULL");
-               appendPQExpBuffer(q, ", ");
-               appendPQExpBuffer(q, "ARRAY[");
+                       appendPQExpBufferStr(q, "NULL");
+               appendPQExpBufferStr(q, ", ");
+               appendPQExpBufferStr(q, "ARRAY[");
                n = 0;
                for (i = 0; i < extinfo->dobj.nDeps; i++)
                {
@@ -7405,12 +8038,12 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                        if (extobj && extobj->objType == DO_EXTENSION)
                        {
                                if (n++ > 0)
-                                       appendPQExpBuffer(q, ",");
+                                       appendPQExpBufferChar(q, ',');
                                appendStringLiteralAH(q, extobj->name, fout);
                        }
                }
-               appendPQExpBuffer(q, "]::pg_catalog.text[]");
-               appendPQExpBuffer(q, ");\n");
+               appendPQExpBufferStr(q, "]::pg_catalog.text[]");
+               appendPQExpBufferStr(q, ");\n");
        }
 
        appendPQExpBuffer(labelq, "EXTENSION %s", qextname);
@@ -7421,7 +8054,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
                                 "",
                                 false, "EXTENSION", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                extinfo->dobj.dependencies, extinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Extension Comments and Security Labels */
@@ -7481,10 +8114,11 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        int                     num,
                                i;
        Oid                     enum_oid;
+       char       *qtypname;
        char       *label;
 
        /* Set proper schema search path */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        if (fout->remoteVersion >= 90100)
                appendPQExpBuffer(query, "SELECT oid, enumlabel "
@@ -7499,11 +8133,12 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                                                  "ORDER BY oid",
                                                  tyinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        num = PQntuples(res);
 
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog.
         * CASCADE shouldn't be required here as for normal types since the I/O
@@ -7512,13 +8147,14 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tyinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
+               binary_upgrade_set_type_oids_by_type_oid(fout, q,
+                                                                                                tyinfo->dobj.catId.oid);
 
        appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        if (!binary_upgrade)
        {
@@ -7527,13 +8163,13 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                {
                        label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
                        if (i > 0)
-                               appendPQExpBuffer(q, ",");
-                       appendPQExpBuffer(q, "\n    ");
+                               appendPQExpBufferChar(q, ',');
+                       appendPQExpBufferStr(q, "\n    ");
                        appendStringLiteralAH(q, label, fout);
                }
        }
 
-       appendPQExpBuffer(q, "\n);\n");
+       appendPQExpBufferStr(q, "\n);\n");
 
        if (binary_upgrade)
        {
@@ -7544,20 +8180,20 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                        label = PQgetvalue(res, i, PQfnumber(res, "enumlabel"));
 
                        if (i == 0)
-                               appendPQExpBuffer(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, must preserve pg_enum oids\n");
                        appendPQExpBuffer(q,
                                                          "SELECT binary_upgrade.set_next_pg_enum_oid('%u'::pg_catalog.oid);\n",
                                                          enum_oid);
                        appendPQExpBuffer(q, "ALTER TYPE %s.",
                                                          fmtId(tyinfo->dobj.namespace->dobj.name));
                        appendPQExpBuffer(q, "%s ADD VALUE ",
-                                                         fmtId(tyinfo->dobj.name));
+                                                         qtypname);
                        appendStringLiteralAH(q, label, fout);
-                       appendPQExpBuffer(q, ";\n\n");
+                       appendPQExpBufferStr(q, ";\n\n");
                }
        }
 
-       appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
 
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
@@ -7569,7 +8205,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->rolname, false,
                                 "TYPE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Type Comments and Security Labels */
@@ -7580,6 +8216,11 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
+       dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+                       qtypname, NULL, tyinfo->dobj.name,
+                       tyinfo->dobj.namespace->dobj.name,
+                       tyinfo->rolname, tyinfo->typacl);
+
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
@@ -7600,16 +8241,17 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
        Oid                     collationOid;
+       char       *qtypname;
        char       *procname;
 
        /*
         * select appropriate schema to ensure names in CREATE are properly
         * qualified
         */
-       selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
 
        appendPQExpBuffer(query,
-                                         "SELECT pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
+                       "SELECT pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, "
                                          "opc.opcname AS opcname, "
                                          "(SELECT nspname FROM pg_catalog.pg_namespace nsp "
                                          "  WHERE nsp.oid = opc.opcnamespace) AS opcnsp, "
@@ -7623,14 +8265,9 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                                          "rngtypid = '%u'",
                                          tyinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-       if (PQntuples(res) != 1)
-       {
-               write_msg(NULL, "query returned %d pg_range entries for range type \"%s\"\n",
-                                 PQntuples(res), tyinfo->dobj.name);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
+
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog.
@@ -7640,13 +8277,14 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tyinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
+               binary_upgrade_set_type_oids_by_type_oid(fout,
+                                                                                                q, tyinfo->dobj.catId.oid);
 
        appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        appendPQExpBuffer(q, "\n    subtype = %s",
                                          PQgetvalue(res, 0, PQfnumber(res, "rngsubtype")));
@@ -7654,13 +8292,13 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        /* print subtype_opclass only if not default for subtype */
        if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't')
        {
-               char *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
-               char *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
+               char       *opcname = PQgetvalue(res, 0, PQfnumber(res, "opcname"));
+               char       *nspname = PQgetvalue(res, 0, PQfnumber(res, "opcnsp"));
 
                /* always schema-qualify, don't try to be smart */
                appendPQExpBuffer(q, ",\n    subtype_opclass = %s.",
                                                  fmtId(nspname));
-               appendPQExpBuffer(q, "%s", fmtId(opcname));
+               appendPQExpBufferStr(q, fmtId(opcname));
        }
 
        collationOid = atooid(PQgetvalue(res, 0, PQfnumber(res, "collation")));
@@ -7673,8 +8311,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                        /* always schema-qualify, don't try to be smart */
                        appendPQExpBuffer(q, ",\n    collation = %s.",
                                                          fmtId(coll->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(q, "%s",
-                                                         fmtId(coll->dobj.name));
+                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
                }
        }
 
@@ -7686,9 +8323,9 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
        if (strcmp(procname, "-") != 0)
                appendPQExpBuffer(q, ",\n    subtype_diff = %s", procname);
 
-       appendPQExpBuffer(q, "\n);\n");
+       appendPQExpBufferStr(q, "\n);\n");
 
-       appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
 
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
@@ -7700,7 +8337,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->rolname, false,
                                 "TYPE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Type Comments and Security Labels */
@@ -7711,6 +8348,11 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
+       dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+                       qtypname, NULL, tyinfo->dobj.name,
+                       tyinfo->dobj.namespace->dobj.name,
+                       tyinfo->rolname, tyinfo->typacl);
+
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
@@ -7730,7 +8372,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
-       int                     ntups;
+       char       *qtypname;
        char       *typlen;
        char       *typinput;
        char       *typoutput;
@@ -7755,7 +8397,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        bool            typdefault_is_literal = false;
 
        /* Set proper schema search path so regproc references list correctly */
-       selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
 
        /* Fetch type-specific details */
        if (fout->remoteVersion >= 90100)
@@ -7931,19 +8573,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
                                                  tyinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        typlen = PQgetvalue(res, 0, PQfnumber(res, "typlen"));
        typinput = PQgetvalue(res, 0, PQfnumber(res, "typinput"));
@@ -7975,6 +8605,8 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        else
                typdefault = NULL;
 
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog.
         * The reason we include CASCADE is that the circular dependency between
@@ -7984,16 +8616,17 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tyinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s CASCADE;\n",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        /* We might already have a shell type, but setting pg_type_oid is harmless */
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
+               binary_upgrade_set_type_oids_by_type_oid(fout, q,
+                                                                                                tyinfo->dobj.catId.oid);
 
        appendPQExpBuffer(q,
                                          "CREATE TYPE %s (\n"
                                          "    INTERNALLENGTH = %s",
-                                         fmtId(tyinfo->dobj.name),
+                                         qtypname,
                                          (strcmp(typlen, "-1") == 0) ? "variable" : typlen);
 
        if (fout->remoteVersion >= 70300)
@@ -8022,11 +8655,11 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
        }
 
        if (strcmp(typcollatable, "t") == 0)
-               appendPQExpBuffer(q, ",\n    COLLATABLE = true");
+               appendPQExpBufferStr(q, ",\n    COLLATABLE = true");
 
        if (typdefault != NULL)
        {
-               appendPQExpBuffer(q, ",\n    DEFAULT = ");
+               appendPQExpBufferStr(q, ",\n    DEFAULT = ");
                if (typdefault_is_literal)
                        appendStringLiteralAH(q, typdefault, fout);
                else
@@ -8038,51 +8671,51 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
                char       *elemType;
 
                /* reselect schema in case changed by function dump */
-               selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
-               elemType = getFormattedTypeName(tyinfo->typelem, zeroAsOpaque);
+               selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
+               elemType = getFormattedTypeName(fout, tyinfo->typelem, zeroAsOpaque);
                appendPQExpBuffer(q, ",\n    ELEMENT = %s", elemType);
                free(elemType);
        }
 
        if (strcmp(typcategory, "U") != 0)
        {
-               appendPQExpBuffer(q, ",\n    CATEGORY = ");
+               appendPQExpBufferStr(q, ",\n    CATEGORY = ");
                appendStringLiteralAH(q, typcategory, fout);
        }
 
        if (strcmp(typispreferred, "t") == 0)
-               appendPQExpBuffer(q, ",\n    PREFERRED = true");
+               appendPQExpBufferStr(q, ",\n    PREFERRED = true");
 
        if (typdelim && strcmp(typdelim, ",") != 0)
        {
-               appendPQExpBuffer(q, ",\n    DELIMITER = ");
+               appendPQExpBufferStr(q, ",\n    DELIMITER = ");
                appendStringLiteralAH(q, typdelim, fout);
        }
 
        if (strcmp(typalign, "c") == 0)
-               appendPQExpBuffer(q, ",\n    ALIGNMENT = char");
+               appendPQExpBufferStr(q, ",\n    ALIGNMENT = char");
        else if (strcmp(typalign, "s") == 0)
-               appendPQExpBuffer(q, ",\n    ALIGNMENT = int2");
+               appendPQExpBufferStr(q, ",\n    ALIGNMENT = int2");
        else if (strcmp(typalign, "i") == 0)
-               appendPQExpBuffer(q, ",\n    ALIGNMENT = int4");
+               appendPQExpBufferStr(q, ",\n    ALIGNMENT = int4");
        else if (strcmp(typalign, "d") == 0)
-               appendPQExpBuffer(q, ",\n    ALIGNMENT = double");
+               appendPQExpBufferStr(q, ",\n    ALIGNMENT = double");
 
        if (strcmp(typstorage, "p") == 0)
-               appendPQExpBuffer(q, ",\n    STORAGE = plain");
+               appendPQExpBufferStr(q, ",\n    STORAGE = plain");
        else if (strcmp(typstorage, "e") == 0)
-               appendPQExpBuffer(q, ",\n    STORAGE = external");
+               appendPQExpBufferStr(q, ",\n    STORAGE = external");
        else if (strcmp(typstorage, "x") == 0)
-               appendPQExpBuffer(q, ",\n    STORAGE = extended");
+               appendPQExpBufferStr(q, ",\n    STORAGE = extended");
        else if (strcmp(typstorage, "m") == 0)
-               appendPQExpBuffer(q, ",\n    STORAGE = main");
+               appendPQExpBufferStr(q, ",\n    STORAGE = main");
 
        if (strcmp(typbyval, "t") == 0)
-               appendPQExpBuffer(q, ",\n    PASSEDBYVALUE");
+               appendPQExpBufferStr(q, ",\n    PASSEDBYVALUE");
 
-       appendPQExpBuffer(q, "\n);\n");
+       appendPQExpBufferStr(q, "\n);\n");
 
-       appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
 
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
@@ -8094,7 +8727,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->rolname, false,
                                 "TYPE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Type Comments and Security Labels */
@@ -8105,6 +8738,11 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
+       dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+                       qtypname, NULL, tyinfo->dobj.name,
+                       tyinfo->dobj.namespace->dobj.name,
+                       tyinfo->rolname, tyinfo->typacl);
+
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
@@ -8124,8 +8762,8 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
-       int                     ntups;
        int                     i;
+       char       *qtypname;
        char       *typnotnull;
        char       *typdefn;
        char       *typdefault;
@@ -8133,10 +8771,10 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        bool            typdefault_is_literal = false;
 
        /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
 
        /* Fetch domain specific details */
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90100)
        {
                /* typcollation is new in 9.1 */
                appendPQExpBuffer(query, "SELECT t.typnotnull, "
@@ -8162,19 +8800,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                                                  tyinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        typnotnull = PQgetvalue(res, 0, PQfnumber(res, "typnotnull"));
        typdefn = PQgetvalue(res, 0, PQfnumber(res, "typdefn"));
@@ -8190,11 +8816,14 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        typcollation = atooid(PQgetvalue(res, 0, PQfnumber(res, "typcollation")));
 
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
+               binary_upgrade_set_type_oids_by_type_oid(fout, q,
+                                                                                                tyinfo->dobj.catId.oid);
+
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
 
        appendPQExpBuffer(q,
                                          "CREATE DOMAIN %s AS %s",
-                                         fmtId(tyinfo->dobj.name),
+                                         qtypname,
                                          typdefn);
 
        /* Print collation only if different from base type's collation */
@@ -8208,17 +8837,16 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                        /* always schema-qualify, don't try to be smart */
                        appendPQExpBuffer(q, " COLLATE %s.",
                                                          fmtId(coll->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(q, "%s",
-                                                         fmtId(coll->dobj.name));
+                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
                }
        }
 
        if (typnotnull[0] == 't')
-               appendPQExpBuffer(q, " NOT NULL");
+               appendPQExpBufferStr(q, " NOT NULL");
 
        if (typdefault != NULL)
        {
-               appendPQExpBuffer(q, " DEFAULT ");
+               appendPQExpBufferStr(q, " DEFAULT ");
                if (typdefault_is_literal)
                        appendStringLiteralAH(q, typdefault, fout);
                else
@@ -8239,7 +8867,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                                                          fmtId(domcheck->dobj.name), domcheck->condef);
        }
 
-       appendPQExpBuffer(q, ";\n");
+       appendPQExpBufferStr(q, ";\n");
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -8247,9 +8875,9 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(delq, "DROP DOMAIN %s.",
                                          fmtId(tyinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
-       appendPQExpBuffer(labelq, "DOMAIN %s", fmtId(tyinfo->dobj.name));
+       appendPQExpBuffer(labelq, "DOMAIN %s", qtypname);
 
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
@@ -8261,7 +8889,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->rolname, false,
                                 "DOMAIN", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Domain Comments and Security Labels */
@@ -8272,6 +8900,11 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
+       dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+                       qtypname, NULL, tyinfo->dobj.name,
+                       tyinfo->dobj.namespace->dobj.name,
+                       tyinfo->rolname, tyinfo->typacl);
+
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
        destroyPQExpBuffer(labelq);
@@ -8292,6 +8925,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        PQExpBuffer labelq = createPQExpBuffer();
        PQExpBuffer query = createPQExpBuffer();
        PGresult   *res;
+       char       *qtypname;
        int                     ntups;
        int                     i_attname;
        int                     i_atttypdefn;
@@ -8304,7 +8938,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        int                     actual_atts;
 
        /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(tyinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tyinfo->dobj.namespace->dobj.name);
 
        /* Fetch type specific details */
        if (fout->remoteVersion >= 90100)
@@ -8348,8 +8982,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                                  tyinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -8365,12 +8998,15 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        {
                Oid                     typrelid = atooid(PQgetvalue(res, 0, i_typrelid));
 
-               binary_upgrade_set_type_oids_by_type_oid(q, tyinfo->dobj.catId.oid);
-               binary_upgrade_set_pg_class_oids(q, typrelid, false);
+               binary_upgrade_set_type_oids_by_type_oid(fout, q,
+                                                                                                tyinfo->dobj.catId.oid);
+               binary_upgrade_set_pg_class_oids(fout, q, typrelid, false);
        }
 
+       qtypname = pg_strdup(fmtId(tyinfo->dobj.name));
+
        appendPQExpBuffer(q, "CREATE TYPE %s AS (",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
        actual_atts = 0;
        for (i = 0; i < ntups; i++)
@@ -8394,8 +9030,8 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 
                /* Format properly if not first attr */
                if (actual_atts++ > 0)
-                       appendPQExpBuffer(q, ",");
-               appendPQExpBuffer(q, "\n\t");
+                       appendPQExpBufferChar(q, ',');
+               appendPQExpBufferStr(q, "\n\t");
 
                if (!attisdropped)
                {
@@ -8412,8 +9048,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                        /* always schema-qualify, don't try to be smart */
                                        appendPQExpBuffer(q, " COLLATE %s.",
                                                                          fmtId(coll->dobj.namespace->dobj.name));
-                                       appendPQExpBuffer(q, "%s",
-                                                                         fmtId(coll->dobj.name));
+                                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
                                }
                        }
                }
@@ -8428,24 +9063,24 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                        appendPQExpBuffer(q, "%s INTEGER /* dummy */", fmtId(attname));
 
                        /* stash separately for insertion after the CREATE TYPE */
-                       appendPQExpBuffer(dropped,
+                       appendPQExpBufferStr(dropped,
                                          "\n-- For binary upgrade, recreate dropped column.\n");
                        appendPQExpBuffer(dropped, "UPDATE pg_catalog.pg_attribute\n"
                                                          "SET attlen = %s, "
                                                          "attalign = '%s', attbyval = false\n"
                                                          "WHERE attname = ", attlen, attalign);
                        appendStringLiteralAH(dropped, attname, fout);
-                       appendPQExpBuffer(dropped, "\n  AND attrelid = ");
-                       appendStringLiteralAH(dropped, fmtId(tyinfo->dobj.name), fout);
-                       appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n");
+                       appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
+                       appendStringLiteralAH(dropped, qtypname, fout);
+                       appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
 
                        appendPQExpBuffer(dropped, "ALTER TYPE %s ",
-                                                         fmtId(tyinfo->dobj.name));
+                                                         qtypname);
                        appendPQExpBuffer(dropped, "DROP ATTRIBUTE %s;\n",
                                                          fmtId(attname));
                }
        }
-       appendPQExpBuffer(q, "\n);\n");
+       appendPQExpBufferStr(q, "\n);\n");
        appendPQExpBufferStr(q, dropped->data);
 
        /*
@@ -8454,9 +9089,9 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
        appendPQExpBuffer(delq, "DROP TYPE %s.",
                                          fmtId(tyinfo->dobj.namespace->dobj.name));
        appendPQExpBuffer(delq, "%s;\n",
-                                         fmtId(tyinfo->dobj.name));
+                                         qtypname);
 
-       appendPQExpBuffer(labelq, "TYPE %s", fmtId(tyinfo->dobj.name));
+       appendPQExpBuffer(labelq, "TYPE %s", qtypname);
 
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tyinfo->dobj, labelq->data);
@@ -8468,7 +9103,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->rolname, false,
                                 "TYPE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
 
@@ -8480,6 +9115,11 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                 tyinfo->dobj.namespace->dobj.name, tyinfo->rolname,
                                 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
 
+       dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+                       qtypname, NULL, tyinfo->dobj.name,
+                       tyinfo->dobj.namespace->dobj.name,
+                       tyinfo->rolname, tyinfo->typacl);
+
        PQclear(res);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(dropped);
@@ -8522,8 +9162,7 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
                                          tyinfo->typrelid);
 
        /* Fetch column attnames */
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        if (ntups < 1)
@@ -8574,13 +9213,12 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
                        resetPQExpBuffer(target);
                        appendPQExpBuffer(target, "COLUMN %s.",
                                                          fmtId(tyinfo->dobj.name));
-                       appendPQExpBuffer(target, "%s",
-                                                         fmtId(attname));
+                       appendPQExpBufferStr(target, fmtId(attname));
 
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query, "COMMENT ON %s IS ", target->data);
                        appendStringLiteralAH(query, descr, fout);
-                       appendPQExpBuffer(query, ";\n");
+                       appendPQExpBufferStr(query, ";\n");
 
                        ArchiveEntry(fout, nilCatalogId, createDumpId(),
                                                 target->data,
@@ -8628,7 +9266,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
         */
 
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_type_oid(q,
+               binary_upgrade_set_type_oids_by_type_oid(fout, q,
                                                                                   stinfo->baseType->dobj.catId.oid);
 
        appendPQExpBuffer(q, "CREATE TYPE %s;\n",
@@ -8641,7 +9279,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
                                 stinfo->baseType->rolname, false,
                                 "SHELL TYPE", SECTION_PRE_DATA,
                                 q->data, "", NULL,
-                                stinfo->dobj.dependencies, stinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        destroyPQExpBuffer(q);
@@ -8770,23 +9408,21 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
                                                  fmtId(funcInfo->dobj.name));
                if (OidIsValid(plang->laninline))
                {
-                       appendPQExpBuffer(defqry, " INLINE ");
+                       appendPQExpBufferStr(defqry, " INLINE ");
                        /* Cope with possibility that inline is in different schema */
                        if (inlineInfo->dobj.namespace != funcInfo->dobj.namespace)
                                appendPQExpBuffer(defqry, "%s.",
                                                           fmtId(inlineInfo->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(defqry, "%s",
-                                                         fmtId(inlineInfo->dobj.name));
+                       appendPQExpBufferStr(defqry, fmtId(inlineInfo->dobj.name));
                }
                if (OidIsValid(plang->lanvalidator))
                {
-                       appendPQExpBuffer(defqry, " VALIDATOR ");
+                       appendPQExpBufferStr(defqry, " VALIDATOR ");
                        /* Cope with possibility that validator is in different schema */
                        if (validatorInfo->dobj.namespace != funcInfo->dobj.namespace)
                                appendPQExpBuffer(defqry, "%s.",
                                                        fmtId(validatorInfo->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(defqry, "%s",
-                                                         fmtId(validatorInfo->dobj.name));
+                       appendPQExpBufferStr(defqry, fmtId(validatorInfo->dobj.name));
                }
        }
        else
@@ -8803,7 +9439,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
                appendPQExpBuffer(defqry, "CREATE OR REPLACE PROCEDURAL LANGUAGE %s",
                                                  qlanname);
        }
-       appendPQExpBuffer(defqry, ";\n");
+       appendPQExpBufferStr(defqry, ";\n");
 
        appendPQExpBuffer(labelq, "LANGUAGE %s", qlanname);
 
@@ -8815,7 +9451,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
                                 lanschema, NULL, plang->lanowner,
                                 false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                                 defqry->data, delqry->data, NULL,
-                                plang->dobj.dependencies, plang->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Proc Lang Comments and Security Labels */
@@ -8843,15 +9479,20 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
  * format_function_arguments: generate function name and argument list
  *
  * This is used when we can rely on pg_get_function_arguments to format
- * the argument list.
+ * the argument list.  Note, however, that pg_get_function_arguments
+ * does not special-case zero-argument aggregates.
  */
 static char *
-format_function_arguments(FuncInfo *finfo, char *funcargs)
+format_function_arguments(FuncInfo *finfo, char *funcargs, bool is_agg)
 {
        PQExpBufferData fn;
 
        initPQExpBuffer(&fn);
-       appendPQExpBuffer(&fn, "%s(%s)", fmtId(finfo->dobj.name), funcargs);
+       appendPQExpBufferStr(&fn, fmtId(finfo->dobj.name));
+       if (is_agg && finfo->nargs == 0)
+               appendPQExpBufferStr(&fn, "(*)");
+       else
+               appendPQExpBuffer(&fn, "(%s)", funcargs);
        return fn.data;
 }
 
@@ -8867,7 +9508,8 @@ format_function_arguments(FuncInfo *finfo, char *funcargs)
  * Any or all of allargtypes, argmodes, argnames may be NULL.
  */
 static char *
-format_function_arguments_old(FuncInfo *finfo, int nallargs,
+format_function_arguments_old(Archive *fout,
+                                                         FuncInfo *finfo, int nallargs,
                                                          char **allargtypes,
                                                          char **argmodes,
                                                          char **argnames)
@@ -8885,7 +9527,7 @@ format_function_arguments_old(FuncInfo *finfo, int nallargs,
                const char *argname;
 
                typid = allargtypes ? atooid(allargtypes[j]) : finfo->argtypes[j];
-               typname = getFormattedTypeName(typid, zeroAsOpaque);
+               typname = getFormattedTypeName(fout, typid, zeroAsOpaque);
 
                if (argmodes)
                {
@@ -8921,7 +9563,7 @@ format_function_arguments_old(FuncInfo *finfo, int nallargs,
                                                  typname);
                free(typname);
        }
-       appendPQExpBuffer(&fn, ")");
+       appendPQExpBufferChar(&fn, ')');
        return fn.data;
 }
 
@@ -8936,7 +9578,7 @@ format_function_arguments_old(FuncInfo *finfo, int nallargs,
  * This is appropriate for use in TOC tags, but not in SQL commands.
  */
 static char *
-format_function_signature(FuncInfo *finfo, bool honor_quotes)
+format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes)
 {
        PQExpBufferData fn;
        int                     j;
@@ -8950,14 +9592,15 @@ format_function_signature(FuncInfo *finfo, bool honor_quotes)
        {
                char       *typname;
 
-               typname = getFormattedTypeName(finfo->argtypes[j], zeroAsOpaque);
+               if (j > 0)
+                       appendPQExpBufferStr(&fn, ", ");
 
-               appendPQExpBuffer(&fn, "%s%s",
-                                                 (j > 0) ? ", " : "",
-                                                 typname);
+               typname = getFormattedTypeName(fout, finfo->argtypes[j],
+                                                                          zeroAsOpaque);
+               appendPQExpBufferStr(&fn, typname);
                free(typname);
        }
-       appendPQExpBuffer(&fn, ")");
+       appendPQExpBufferChar(&fn, ')');
        return fn.data;
 }
 
@@ -8976,9 +9619,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        PQExpBuffer asPart;
        PGresult   *res;
        char       *funcsig;            /* identity signature */
-       char       *funcfullsig;        /* full signature */
+       char       *funcfullsig = NULL; /* full signature */
        char       *funcsig_tag;
-       int                     ntups;
        char       *proretset;
        char       *prosrc;
        char       *probin;
@@ -8992,6 +9634,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        char       *provolatile;
        char       *proisstrict;
        char       *prosecdef;
+       char       *proleakproof;
        char       *proconfig;
        char       *procost;
        char       *prorows;
@@ -9016,10 +9659,27 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        asPart = createPQExpBuffer();
 
        /* Set proper schema search path so type references list correctly */
-       selectSourceSchema(finfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, finfo->dobj.namespace->dobj.name);
 
        /* Fetch function-specific details */
-       if (g_fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 90200)
+       {
+               /*
+                * proleakproof was added at v9.2
+                */
+               appendPQExpBuffer(query,
+                                                 "SELECT proretset, prosrc, probin, "
+                                       "pg_catalog.pg_get_function_arguments(oid) AS funcargs, "
+                 "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
+                                        "pg_catalog.pg_get_function_result(oid) AS funcresult, "
+                                                 "proiswindow, provolatile, proisstrict, prosecdef, "
+                                                 "proleakproof, proconfig, procost, prorows, "
+                                                 "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
+                                                 "FROM pg_catalog.pg_proc "
+                                                 "WHERE oid = '%u'::pg_catalog.oid",
+                                                 finfo->dobj.catId.oid);
+       }
+       else if (fout->remoteVersion >= 80400)
        {
                /*
                 * In 8.4 and up we rely on pg_get_function_arguments and
@@ -9031,39 +9691,42 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                  "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, "
                                         "pg_catalog.pg_get_function_result(oid) AS funcresult, "
                                                  "proiswindow, provolatile, proisstrict, prosecdef, "
-                                                 "proconfig, procost, prorows, "
+                                                 "false AS proleakproof, "
+                                                 " proconfig, procost, prorows, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_catalog.pg_proc "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  finfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 80300)
+       else if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
                                                  "proallargtypes, proargmodes, proargnames, "
                                                  "false AS proiswindow, "
                                                  "provolatile, proisstrict, prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "proconfig, procost, prorows, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_catalog.pg_proc "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  finfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 80100)
+       else if (fout->remoteVersion >= 80100)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
                                                  "proallargtypes, proargmodes, proargnames, "
                                                  "false AS proiswindow, "
                                                  "provolatile, proisstrict, prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "null AS proconfig, 0 AS procost, 0 AS prorows, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_catalog.pg_proc "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  finfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 80000)
+       else if (fout->remoteVersion >= 80000)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
@@ -9072,13 +9735,14 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                                  "proargnames, "
                                                  "false AS proiswindow, "
                                                  "provolatile, proisstrict, prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "null AS proconfig, 0 AS procost, 0 AS prorows, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_catalog.pg_proc "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  finfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
@@ -9087,13 +9751,14 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                                  "null AS proargnames, "
                                                  "false AS proiswindow, "
                                                  "provolatile, proisstrict, prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "null AS proconfig, 0 AS procost, 0 AS prorows, "
                                                  "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_catalog.pg_proc "
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  finfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query,
                                                  "SELECT proretset, prosrc, probin, "
@@ -9104,6 +9769,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                         "case when proiscachable then 'i' else 'v' end AS provolatile, "
                                                  "proisstrict, "
                                                  "false AS prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "null AS proconfig, 0 AS procost, 0 AS prorows, "
                  "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_proc "
@@ -9121,6 +9787,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                         "CASE WHEN proiscachable THEN 'i' ELSE 'v' END AS provolatile, "
                                                  "false AS proisstrict, "
                                                  "false AS prosecdef, "
+                                                 "false AS proleakproof, "
                                                  "NULL AS proconfig, 0 AS procost, 0 AS prorows, "
                  "(SELECT lanname FROM pg_language WHERE oid = prolang) AS lanname "
                                                  "FROM pg_proc "
@@ -9128,24 +9795,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                                  finfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        proretset = PQgetvalue(res, 0, PQfnumber(res, "proretset"));
        prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc"));
        probin = PQgetvalue(res, 0, PQfnumber(res, "probin"));
-       if (g_fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 80400)
        {
                funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
                funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
@@ -9163,6 +9818,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        provolatile = PQgetvalue(res, 0, PQfnumber(res, "provolatile"));
        proisstrict = PQgetvalue(res, 0, PQfnumber(res, "proisstrict"));
        prosecdef = PQgetvalue(res, 0, PQfnumber(res, "prosecdef"));
+       proleakproof = PQgetvalue(res, 0, PQfnumber(res, "proleakproof"));
        proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig"));
        procost = PQgetvalue(res, 0, PQfnumber(res, "procost"));
        prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows"));
@@ -9176,11 +9832,11 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
         */
        if (probin[0] != '\0' && strcmp(probin, "-") != 0)
        {
-               appendPQExpBuffer(asPart, "AS ");
+               appendPQExpBufferStr(asPart, "AS ");
                appendStringLiteralAH(asPart, probin, fout);
                if (strcmp(prosrc, "-") != 0)
                {
-                       appendPQExpBuffer(asPart, ", ");
+                       appendPQExpBufferStr(asPart, ", ");
 
                        /*
                         * where we have bin, use dollar quoting if allowed and src
@@ -9197,7 +9853,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        {
                if (strcmp(prosrc, "-") != 0)
                {
-                       appendPQExpBuffer(asPart, "AS ");
+                       appendPQExpBufferStr(asPart, "AS ");
                        /* with no bin, dollar quote src unconditionally if allowed */
                        if (disable_dollar_quoting)
                                appendStringLiteralAH(asPart, prosrc, fout);
@@ -9267,18 +9923,16 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        if (funcargs)
        {
                /* 8.4 or later; we rely on server-side code for most of the work */
-               funcfullsig = format_function_arguments(finfo, funcargs);
-               funcsig = format_function_arguments(finfo, funciargs);
+               funcfullsig = format_function_arguments(finfo, funcargs, false);
+               funcsig = format_function_arguments(finfo, funciargs, false);
        }
        else
-       {
                /* pre-8.4, do it ourselves */
-               funcsig = format_function_arguments_old(finfo, nallargs, allargtypes,
+               funcsig = format_function_arguments_old(fout,
+                                                                                               finfo, nallargs, allargtypes,
                                                                                                argmodes, argnames);
-               funcfullsig = funcsig;
-       }
 
-       funcsig_tag = format_function_signature(finfo, false);
+       funcsig_tag = format_function_signature(fout, finfo, false);
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -9287,12 +9941,14 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                          fmtId(finfo->dobj.namespace->dobj.name),
                                          funcsig);
 
-       appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig);
+       appendPQExpBuffer(q, "CREATE FUNCTION %s ", funcfullsig ? funcfullsig :
+                                         funcsig);
        if (funcresult)
                appendPQExpBuffer(q, "RETURNS %s", funcresult);
        else
        {
-               rettypename = getFormattedTypeName(finfo->prorettype, zeroAsOpaque);
+               rettypename = getFormattedTypeName(fout, finfo->prorettype,
+                                                                                  zeroAsOpaque);
                appendPQExpBuffer(q, "RETURNS %s%s",
                                                  (proretset[0] == 't') ? "SETOF " : "",
                                                  rettypename);
@@ -9302,27 +9958,27 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        appendPQExpBuffer(q, "\n    LANGUAGE %s", fmtId(lanname));
 
        if (proiswindow[0] == 't')
-               appendPQExpBuffer(q, " WINDOW");
+               appendPQExpBufferStr(q, " WINDOW");
 
        if (provolatile[0] != PROVOLATILE_VOLATILE)
        {
                if (provolatile[0] == PROVOLATILE_IMMUTABLE)
-                       appendPQExpBuffer(q, " IMMUTABLE");
+                       appendPQExpBufferStr(q, " IMMUTABLE");
                else if (provolatile[0] == PROVOLATILE_STABLE)
-                       appendPQExpBuffer(q, " STABLE");
+                       appendPQExpBufferStr(q, " STABLE");
                else if (provolatile[0] != PROVOLATILE_VOLATILE)
-               {
-                       write_msg(NULL, "unrecognized provolatile value for function \"%s\"\n",
-                                         finfo->dobj.name);
-                       exit_nicely();
-               }
+                       exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n",
+                                                 finfo->dobj.name);
        }
 
        if (proisstrict[0] == 't')
-               appendPQExpBuffer(q, " STRICT");
+               appendPQExpBufferStr(q, " STRICT");
 
        if (prosecdef[0] == 't')
-               appendPQExpBuffer(q, " SECURITY DEFINER");
+               appendPQExpBufferStr(q, " SECURITY DEFINER");
+
+       if (proleakproof[0] == 't')
+               appendPQExpBufferStr(q, " LEAKPROOF");
 
        /*
         * COST and ROWS are emitted only if present and not default, so as not to
@@ -9366,7 +10022,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                 */
                if (pg_strcasecmp(configitem, "DateStyle") == 0
                        || pg_strcasecmp(configitem, "search_path") == 0)
-                       appendPQExpBuffer(q, "%s", pos);
+                       appendPQExpBufferStr(q, pos);
                else
                        appendStringLiteralAH(q, pos, fout);
        }
@@ -9385,7 +10041,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
                                 finfo->rolname, false,
                                 "FUNCTION", SECTION_PRE_DATA,
                                 q->data, delqry->data, NULL,
-                                finfo->dobj.dependencies, finfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Function Comments and Security Labels */
@@ -9409,6 +10065,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
        destroyPQExpBuffer(labelq);
        destroyPQExpBuffer(asPart);
        free(funcsig);
+       if (funcfullsig)
+               free(funcfullsig);
        free(funcsig_tag);
        if (allargtypes)
                free(allargtypes);
@@ -9494,52 +10152,58 @@ dumpCast(Archive *fout, CastInfo *cast)
        }
 
        /* Make sure we are in proper schema (needed for getFormattedTypeName) */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        defqry = createPQExpBuffer();
        delqry = createPQExpBuffer();
        labelq = createPQExpBuffer();
 
        appendPQExpBuffer(delqry, "DROP CAST (%s AS %s);\n",
-                                         getFormattedTypeName(cast->castsource, zeroAsNone),
-                                         getFormattedTypeName(cast->casttarget, zeroAsNone));
+                                       getFormattedTypeName(fout, cast->castsource, zeroAsNone),
+                                  getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
 
        appendPQExpBuffer(defqry, "CREATE CAST (%s AS %s) ",
-                                         getFormattedTypeName(cast->castsource, zeroAsNone),
-                                         getFormattedTypeName(cast->casttarget, zeroAsNone));
+                                       getFormattedTypeName(fout, cast->castsource, zeroAsNone),
+                                  getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
 
        switch (cast->castmethod)
        {
                case COERCION_METHOD_BINARY:
-                       appendPQExpBuffer(defqry, "WITHOUT FUNCTION");
+                       appendPQExpBufferStr(defqry, "WITHOUT FUNCTION");
                        break;
                case COERCION_METHOD_INOUT:
-                       appendPQExpBuffer(defqry, "WITH INOUT");
+                       appendPQExpBufferStr(defqry, "WITH INOUT");
                        break;
                case COERCION_METHOD_FUNCTION:
+                       if (funcInfo)
+                       {
+                               char       *fsig = format_function_signature(fout, funcInfo, true);
 
-                       /*
-                        * Always qualify the function name, in case it is not in
-                        * pg_catalog schema (format_function_signature won't qualify it).
-                        */
-                       appendPQExpBuffer(defqry, "WITH FUNCTION %s.",
-                                                         fmtId(funcInfo->dobj.namespace->dobj.name));
-                       appendPQExpBuffer(defqry, "%s",
-                                                         format_function_signature(funcInfo, true));
+                               /*
+                                * Always qualify the function name, in case it is not in
+                                * pg_catalog schema (format_function_signature won't qualify
+                                * it).
+                                */
+                               appendPQExpBuffer(defqry, "WITH FUNCTION %s.%s",
+                                                  fmtId(funcInfo->dobj.namespace->dobj.name), fsig);
+                               free(fsig);
+                       }
+                       else
+                               write_msg(NULL, "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n");
                        break;
                default:
                        write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n");
        }
 
        if (cast->castcontext == 'a')
-               appendPQExpBuffer(defqry, " AS ASSIGNMENT");
+               appendPQExpBufferStr(defqry, " AS ASSIGNMENT");
        else if (cast->castcontext == 'i')
-               appendPQExpBuffer(defqry, " AS IMPLICIT");
-       appendPQExpBuffer(defqry, ";\n");
+               appendPQExpBufferStr(defqry, " AS IMPLICIT");
+       appendPQExpBufferStr(defqry, ";\n");
 
        appendPQExpBuffer(labelq, "CAST (%s AS %s)",
-                                         getFormattedTypeName(cast->castsource, zeroAsNone),
-                                         getFormattedTypeName(cast->casttarget, zeroAsNone));
+                                       getFormattedTypeName(fout, cast->castsource, zeroAsNone),
+                                  getFormattedTypeName(fout, cast->casttarget, zeroAsNone));
 
        if (binary_upgrade)
                binary_upgrade_extension_member(defqry, &cast->dobj, labelq->data);
@@ -9549,7 +10213,7 @@ dumpCast(Archive *fout, CastInfo *cast)
                                 "pg_catalog", NULL, "",
                                 false, "CAST", SECTION_PRE_DATA,
                                 defqry->data, delqry->data, NULL,
-                                cast->dobj.dependencies, cast->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Cast Comments */
@@ -9577,7 +10241,6 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        PQExpBuffer details;
        const char *name;
        PGresult   *res;
-       int                     ntups;
        int                     i_oprkind;
        int                     i_oprcode;
        int                     i_oprleft;
@@ -9598,6 +10261,8 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        char       *oprjoin;
        char       *oprcanmerge;
        char       *oprcanhash;
+       char       *oprregproc;
+       char       *oprref;
 
        /* Skip if not to be dumped */
        if (!oprinfo->dobj.dump || dataOnly)
@@ -9618,9 +10283,9 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        details = createPQExpBuffer();
 
        /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(oprinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, oprinfo->dobj.namespace->dobj.name);
 
-       if (g_fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT oprkind, "
                                                  "oprcode::pg_catalog.regprocedure, "
@@ -9635,7 +10300,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  oprinfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT oprkind, "
                                                  "oprcode::pg_catalog.regprocedure, "
@@ -9651,7 +10316,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                                                  "WHERE oid = '%u'::pg_catalog.oid",
                                                  oprinfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT oprkind, oprcode, "
                                                  "CASE WHEN oprleft = 0 THEN '-' "
@@ -9680,19 +10345,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                                                  oprinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_oprkind = PQfnumber(res, "oprkind");
        i_oprcode = PQfnumber(res, "oprcode");
@@ -9716,8 +10369,12 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge);
        oprcanhash = PQgetvalue(res, 0, i_oprcanhash);
 
-       appendPQExpBuffer(details, "    PROCEDURE = %s",
-                                         convertRegProcReference(oprcode));
+       oprregproc = convertRegProcReference(fout, oprcode);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, "    PROCEDURE = %s", oprregproc);
+               free(oprregproc);
+       }
 
        appendPQExpBuffer(oprid, "%s (",
                                          oprinfo->dobj.name);
@@ -9729,20 +10386,20 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
        if (strcmp(oprkind, "r") == 0 ||
                strcmp(oprkind, "b") == 0)
        {
-               if (g_fout->remoteVersion >= 70100)
+               if (fout->remoteVersion >= 70100)
                        name = oprleft;
                else
                        name = fmtId(oprleft);
                appendPQExpBuffer(details, ",\n    LEFTARG = %s", name);
-               appendPQExpBuffer(oprid, "%s", name);
+               appendPQExpBufferStr(oprid, name);
        }
        else
-               appendPQExpBuffer(oprid, "NONE");
+               appendPQExpBufferStr(oprid, "NONE");
 
        if (strcmp(oprkind, "l") == 0 ||
                strcmp(oprkind, "b") == 0)
        {
-               if (g_fout->remoteVersion >= 70100)
+               if (fout->remoteVersion >= 70100)
                        name = oprright;
                else
                        name = fmtId(oprright);
@@ -9750,29 +10407,41 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                appendPQExpBuffer(oprid, ", %s)", name);
        }
        else
-               appendPQExpBuffer(oprid, ", NONE)");
+               appendPQExpBufferStr(oprid, ", NONE)");
 
-       name = convertOperatorReference(oprcom);
-       if (name)
-               appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", name);
+       oprref = convertOperatorReference(fout, oprcom);
+       if (oprref)
+       {
+               appendPQExpBuffer(details, ",\n    COMMUTATOR = %s", oprref);
+               free(oprref);
+       }
 
-       name = convertOperatorReference(oprnegate);
-       if (name)
-               appendPQExpBuffer(details, ",\n    NEGATOR = %s", name);
+       oprref = convertOperatorReference(fout, oprnegate);
+       if (oprref)
+       {
+               appendPQExpBuffer(details, ",\n    NEGATOR = %s", oprref);
+               free(oprref);
+       }
 
        if (strcmp(oprcanmerge, "t") == 0)
-               appendPQExpBuffer(details, ",\n    MERGES");
+               appendPQExpBufferStr(details, ",\n    MERGES");
 
        if (strcmp(oprcanhash, "t") == 0)
-               appendPQExpBuffer(details, ",\n    HASHES");
+               appendPQExpBufferStr(details, ",\n    HASHES");
 
-       name = convertRegProcReference(oprrest);
-       if (name)
-               appendPQExpBuffer(details, ",\n    RESTRICT = %s", name);
+       oprregproc = convertRegProcReference(fout, oprrest);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, ",\n    RESTRICT = %s", oprregproc);
+               free(oprregproc);
+       }
 
-       name = convertRegProcReference(oprjoin);
-       if (name)
-               appendPQExpBuffer(details, ",\n    JOIN = %s", name);
+       oprregproc = convertRegProcReference(fout, oprjoin);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, ",\n    JOIN = %s", oprregproc);
+               free(oprregproc);
+       }
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -9796,7 +10465,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                                 oprinfo->rolname,
                                 false, "OPERATOR", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                oprinfo->dobj.dependencies, oprinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Operator Comments */
@@ -9817,19 +10486,20 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 /*
  * Convert a function reference obtained from pg_operator
  *
- * Returns what to print, or NULL if function references is InvalidOid
+ * Returns allocated string of what to print, or NULL if function references
+ * is InvalidOid. Returned string is expected to be free'd by the caller.
  *
  * In 7.3 the input is a REGPROCEDURE display; we have to strip the
  * argument-types part.  In prior versions, the input is a REGPROC display.
  */
-static const char *
-convertRegProcReference(const char *proc)
+static char *
+convertRegProcReference(Archive *fout, const char *proc)
 {
        /* In all cases "-" means a null reference */
        if (strcmp(proc, "-") == 0)
                return NULL;
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                char       *name;
                char       *paren;
@@ -9852,21 +10522,22 @@ convertRegProcReference(const char *proc)
        }
 
        /* REGPROC before 7.3 does not quote its result */
-       return fmtId(proc);
+       return pg_strdup(fmtId(proc));
 }
 
 /*
  * Convert an operator cross-reference obtained from pg_operator
  *
- * Returns what to print, or NULL to print nothing
+ * Returns an allocated string of what to print, or NULL to print nothing.
+ * Caller is responsible for free'ing result string.
  *
  * In 7.3 and up the input is a REGOPERATOR display; we have to strip the
  * argument-types part, and add OPERATOR() decoration if the name is
  * schema-qualified.  In older versions, the input is just a numeric OID,
  * which we search our operator list for.
  */
-static const char *
-convertOperatorReference(const char *opr)
+static char *
+convertOperatorReference(Archive *fout, const char *opr)
 {
        OprInfo    *oprInfo;
 
@@ -9874,7 +10545,7 @@ convertOperatorReference(const char *opr)
        if (strcmp(opr, "0") == 0)
                return NULL;
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                char       *name;
                char       *oname;
@@ -9901,8 +10572,7 @@ convertOperatorReference(const char *opr)
                /* If not schema-qualified, don't need to add OPERATOR() */
                if (!sawdot)
                        return name;
-               oname = pg_malloc(strlen(name) + 11);
-               sprintf(oname, "OPERATOR(%s)", name);
+               oname = psprintf("OPERATOR(%s)", name);
                free(name);
                return oname;
        }
@@ -9914,7 +10584,7 @@ convertOperatorReference(const char *opr)
                                  opr);
                return NULL;
        }
-       return oprInfo->dobj.name;
+       return pg_strdup(oprInfo->dobj.name);
 }
 
 /*
@@ -9926,27 +10596,15 @@ convertOperatorReference(const char *opr)
  * are search path dependent!
  */
 static const char *
-convertTSFunction(Oid funcOid)
+convertTSFunction(Archive *fout, Oid funcOid)
 {
        char       *result;
        char            query[128];
        PGresult   *res;
-       int                     ntups;
 
        snprintf(query, sizeof(query),
                         "SELECT '%u'::pg_catalog.regproc", funcOid);
-       res = PQexec(g_conn, query);
-       check_sql_result(res, g_conn, query, PGRES_TUPLES_OK);
-
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query);
 
        result = pg_strdup(PQgetvalue(res, 0, 0));
 
@@ -10013,7 +10671,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
         * pre-7.3 databases.  This could be done but it seems not worth the
         * trouble.
         */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
                return;
 
        query = createPQExpBuffer();
@@ -10022,10 +10680,10 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(opcinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, opcinfo->dobj.namespace->dobj.name);
 
        /* Get additional fields from the pg_opclass row */
-       if (g_fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT opcintype::pg_catalog.regtype, "
                                                  "opckeytype::pg_catalog.regtype, "
@@ -10052,19 +10710,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  opcinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_opcintype = PQfnumber(res, "opcintype");
        i_opckeytype = PQfnumber(res, "opckeytype");
@@ -10098,7 +10744,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
        appendPQExpBuffer(q, "CREATE OPERATOR CLASS %s\n    ",
                                          fmtId(opcinfo->dobj.name));
        if (strcmp(opcdefault, "t") == 0)
-               appendPQExpBuffer(q, "DEFAULT ");
+               appendPQExpBufferStr(q, "DEFAULT ");
        appendPQExpBuffer(q, "FOR TYPE %s USING %s",
                                          opcintype,
                                          fmtId(amname));
@@ -10106,12 +10752,12 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                (strcmp(opcfamilyname, opcinfo->dobj.name) != 0 ||
                 strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0))
        {
-               appendPQExpBuffer(q, " FAMILY ");
+               appendPQExpBufferStr(q, " FAMILY ");
                if (strcmp(opcfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
                        appendPQExpBuffer(q, "%s.", fmtId(opcfamilynsp));
                appendPQExpBuffer(q, "%s", fmtId(opcfamilyname));
        }
-       appendPQExpBuffer(q, " AS\n    ");
+       appendPQExpBufferStr(q, " AS\n    ");
 
        needComma = false;
 
@@ -10138,7 +10784,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
         */
        resetPQExpBuffer(query);
 
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90100)
        {
                appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator, "
@@ -10155,7 +10801,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  opcinfo->dobj.catId.oid,
                                                  opcfamily);
        }
-       else if (g_fout->remoteVersion >= 80400)
+       else if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator, "
@@ -10169,7 +10815,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  "ORDER BY amopstrategy",
                                                  opcinfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 80300)
+       else if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT amopstrategy, amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator, "
@@ -10199,8 +10845,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  opcinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -10219,21 +10864,21 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                sortfamilynsp = PQgetvalue(res, i, i_sortfamilynsp);
 
                if (needComma)
-                       appendPQExpBuffer(q, " ,\n    ");
+                       appendPQExpBufferStr(q, " ,\n    ");
 
                appendPQExpBuffer(q, "OPERATOR %s %s",
                                                  amopstrategy, amopopr);
 
                if (strlen(sortfamily) > 0)
                {
-                       appendPQExpBuffer(q, " FOR ORDER BY ");
+                       appendPQExpBufferStr(q, " FOR ORDER BY ");
                        if (strcmp(sortfamilynsp, opcinfo->dobj.namespace->dobj.name) != 0)
                                appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
-                       appendPQExpBuffer(q, "%s", fmtId(sortfamily));
+                       appendPQExpBufferStr(q, fmtId(sortfamily));
                }
 
                if (strcmp(amopreqcheck, "t") == 0)
-                       appendPQExpBuffer(q, " RECHECK");
+                       appendPQExpBufferStr(q, " RECHECK");
 
                needComma = true;
        }
@@ -10254,7 +10899,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
         */
        resetPQExpBuffer(query);
 
-       if (g_fout->remoteVersion >= 80300)
+       if (fout->remoteVersion >= 80300)
        {
                appendPQExpBuffer(query, "SELECT amprocnum, "
                                                  "amproc::pg_catalog.regprocedure, "
@@ -10280,8 +10925,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                                  opcinfo->dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -10298,7 +10942,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                amprocrighttype = PQgetvalue(res, i, i_amprocrighttype);
 
                if (needComma)
-                       appendPQExpBuffer(q, " ,\n    ");
+                       appendPQExpBufferStr(q, " ,\n    ");
 
                appendPQExpBuffer(q, "FUNCTION %s", amprocnum);
 
@@ -10312,7 +10956,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 
        PQclear(res);
 
-       appendPQExpBuffer(q, ";\n");
+       appendPQExpBufferStr(q, ";\n");
 
        appendPQExpBuffer(labelq, "OPERATOR CLASS %s",
                                          fmtId(opcinfo->dobj.name));
@@ -10329,7 +10973,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
                                 opcinfo->rolname,
                                 false, "OPERATOR CLASS", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                opcinfo->dobj.dependencies, opcinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Operator Class Comments */
@@ -10404,7 +11048,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema so regoperator works correctly */
-       selectSourceSchema(opfinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, opfinfo->dobj.namespace->dobj.name);
 
        /*
         * Fetch only those opfamily members that are tied directly to the
@@ -10416,7 +11060,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
         * older server and then reload into that old version.  This can go away
         * once 8.3 is so old as to not be of interest to anyone.
         */
-       if (g_fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90100)
        {
                appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator, "
@@ -10433,7 +11077,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                                  opfinfo->dobj.catId.oid,
                                                  opfinfo->dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 80400)
+       else if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query, "SELECT amopstrategy, false AS amopreqcheck, "
                                                  "amopopr::pg_catalog.regoperator, "
@@ -10462,8 +11106,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                                  opfinfo->dobj.catId.oid);
        }
 
-       res_ops = PQexec(g_conn, query->data);
-       check_sql_result(res_ops, g_conn, query->data, PGRES_TUPLES_OK);
+       res_ops = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        resetPQExpBuffer(query);
 
@@ -10479,8 +11122,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                          "ORDER BY amprocnum",
                                          opfinfo->dobj.catId.oid);
 
-       res_procs = PQexec(g_conn, query->data);
-       check_sql_result(res_procs, g_conn, query->data, PGRES_TUPLES_OK);
+       res_procs = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        if (PQntuples(res_ops) == 0 && PQntuples(res_procs) == 0)
        {
@@ -10498,8 +11140,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                                  "LIMIT 1",
                                                  opfinfo->dobj.catId.oid);
 
-               res = PQexec(g_conn, query->data);
-               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+               res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
                if (PQntuples(res) == 0)
                {
@@ -10526,19 +11167,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                          "WHERE oid = '%u'::pg_catalog.oid",
                                          opfinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_amname = PQfnumber(res, "amname");
 
@@ -10593,21 +11222,21 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                        sortfamilynsp = PQgetvalue(res_ops, i, i_sortfamilynsp);
 
                        if (needComma)
-                               appendPQExpBuffer(q, " ,\n    ");
+                               appendPQExpBufferStr(q, " ,\n    ");
 
                        appendPQExpBuffer(q, "OPERATOR %s %s",
                                                          amopstrategy, amopopr);
 
                        if (strlen(sortfamily) > 0)
                        {
-                               appendPQExpBuffer(q, " FOR ORDER BY ");
+                               appendPQExpBufferStr(q, " FOR ORDER BY ");
                                if (strcmp(sortfamilynsp, opfinfo->dobj.namespace->dobj.name) != 0)
                                        appendPQExpBuffer(q, "%s.", fmtId(sortfamilynsp));
-                               appendPQExpBuffer(q, "%s", fmtId(sortfamily));
+                               appendPQExpBufferStr(q, fmtId(sortfamily));
                        }
 
                        if (strcmp(amopreqcheck, "t") == 0)
-                               appendPQExpBuffer(q, " RECHECK");
+                               appendPQExpBufferStr(q, " RECHECK");
 
                        needComma = true;
                }
@@ -10630,7 +11259,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                        amprocrighttype = PQgetvalue(res_procs, i, i_amprocrighttype);
 
                        if (needComma)
-                               appendPQExpBuffer(q, " ,\n    ");
+                               appendPQExpBufferStr(q, " ,\n    ");
 
                        appendPQExpBuffer(q, "FUNCTION %s (%s, %s) %s",
                                                          amprocnum, amproclefttype, amprocrighttype,
@@ -10639,7 +11268,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                        needComma = true;
                }
 
-               appendPQExpBuffer(q, ";\n");
+               appendPQExpBufferStr(q, ";\n");
        }
 
        appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
@@ -10657,7 +11286,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                                 opfinfo->rolname,
                                 false, "OPERATOR FAMILY", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                opfinfo->dobj.dependencies, opfinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Operator Family Comments */
@@ -10686,7 +11315,6 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        PQExpBuffer delq;
        PQExpBuffer labelq;
        PGresult   *res;
-       int                     ntups;
        int                     i_collcollate;
        int                     i_collctype;
        const char *collcollate;
@@ -10702,7 +11330,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(collinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, collinfo->dobj.namespace->dobj.name);
 
        /* Get conversion-specific details */
        appendPQExpBuffer(query, "SELECT "
@@ -10712,19 +11340,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
                                          "WHERE c.oid = '%u'::pg_catalog.oid",
                                          collinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_collcollate = PQfnumber(res, "collcollate");
        i_collctype = PQfnumber(res, "collctype");
@@ -10743,9 +11359,9 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
        appendPQExpBuffer(q, "CREATE COLLATION %s (lc_collate = ",
                                          fmtId(collinfo->dobj.name));
        appendStringLiteralAH(q, collcollate, fout);
-       appendPQExpBuffer(q, ", lc_ctype = ");
+       appendPQExpBufferStr(q, ", lc_ctype = ");
        appendStringLiteralAH(q, collctype, fout);
-       appendPQExpBuffer(q, ");\n");
+       appendPQExpBufferStr(q, ");\n");
 
        appendPQExpBuffer(labelq, "COLLATION %s", fmtId(collinfo->dobj.name));
 
@@ -10759,7 +11375,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
                                 collinfo->rolname,
                                 false, "COLLATION", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                collinfo->dobj.dependencies, collinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Collation Comments */
@@ -10787,7 +11403,6 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        PQExpBuffer delq;
        PQExpBuffer labelq;
        PGresult   *res;
-       int                     ntups;
        int                     i_conforencoding;
        int                     i_contoencoding;
        int                     i_conproc;
@@ -10807,7 +11422,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(convinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, convinfo->dobj.namespace->dobj.name);
 
        /* Get conversion-specific details */
        appendPQExpBuffer(query, "SELECT "
@@ -10818,19 +11433,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
                                          "WHERE c.oid = '%u'::pg_catalog.oid",
                                          convinfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_conforencoding = PQfnumber(res, "conforencoding");
        i_contoencoding = PQfnumber(res, "contoencoding");
@@ -10854,7 +11457,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
                                          (condefault) ? "DEFAULT " : "",
                                          fmtId(convinfo->dobj.name));
        appendStringLiteralAH(q, conforencoding, fout);
-       appendPQExpBuffer(q, " TO ");
+       appendPQExpBufferStr(q, " TO ");
        appendStringLiteralAH(q, contoencoding, fout);
        /* regproc is automatically quoted in 7.3 and above */
        appendPQExpBuffer(q, " FROM %s;\n", conproc);
@@ -10871,7 +11474,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
                                 convinfo->rolname,
                                 false, "CONVERSION", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                convinfo->dobj.dependencies, convinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Conversion Comments */
@@ -10901,28 +11504,28 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
 
        initPQExpBuffer(&buf);
        if (honor_quotes)
-               appendPQExpBuffer(&buf, "%s",
-                                                 fmtId(agginfo->aggfn.dobj.name));
+               appendPQExpBufferStr(&buf, fmtId(agginfo->aggfn.dobj.name));
        else
-               appendPQExpBuffer(&buf, "%s", agginfo->aggfn.dobj.name);
+               appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name);
 
        if (agginfo->aggfn.nargs == 0)
                appendPQExpBuffer(&buf, "(*)");
        else
        {
-               appendPQExpBuffer(&buf, "(");
+               appendPQExpBufferChar(&buf, '(');
                for (j = 0; j < agginfo->aggfn.nargs; j++)
                {
                        char       *typname;
 
-                       typname = getFormattedTypeName(agginfo->aggfn.argtypes[j], zeroAsOpaque);
+                       typname = getFormattedTypeName(fout, agginfo->aggfn.argtypes[j],
+                                                                                  zeroAsOpaque);
 
                        appendPQExpBuffer(&buf, "%s%s",
                                                          (j > 0) ? ", " : "",
                                                          typname);
                        free(typname);
                }
-               appendPQExpBuffer(&buf, ")");
+               appendPQExpBufferChar(&buf, ')');
        }
        return buf.data;
 }
@@ -10939,21 +11542,42 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        PQExpBuffer delq;
        PQExpBuffer labelq;
        PQExpBuffer details;
-       char       *aggsig;
+       char       *aggsig;                     /* identity signature */
+       char       *aggfullsig = NULL;          /* full signature */
        char       *aggsig_tag;
        PGresult   *res;
-       int                     ntups;
        int                     i_aggtransfn;
        int                     i_aggfinalfn;
+       int                     i_aggmtransfn;
+       int                     i_aggminvtransfn;
+       int                     i_aggmfinalfn;
+       int                     i_aggfinalextra;
+       int                     i_aggmfinalextra;
        int                     i_aggsortop;
+       int                     i_hypothetical;
        int                     i_aggtranstype;
+       int                     i_aggtransspace;
+       int                     i_aggmtranstype;
+       int                     i_aggmtransspace;
        int                     i_agginitval;
+       int                     i_aggminitval;
        int                     i_convertok;
        const char *aggtransfn;
        const char *aggfinalfn;
+       const char *aggmtransfn;
+       const char *aggminvtransfn;
+       const char *aggmfinalfn;
+       bool            aggfinalextra;
+       bool            aggmfinalextra;
        const char *aggsortop;
+       char       *aggsortconvop;
+       bool            hypothetical;
        const char *aggtranstype;
+       const char *aggtransspace;
+       const char *aggmtranstype;
+       const char *aggmtransspace;
        const char *agginitval;
+       const char *aggminitval;
        bool            convertok;
 
        /* Skip if not to be dumped */
@@ -10967,40 +11591,93 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        details = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(agginfo->aggfn.dobj.namespace->dobj.name);
+       selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
 
        /* Get aggregate-specific details */
-       if (g_fout->remoteVersion >= 80100)
+       if (fout->remoteVersion >= 90400)
+       {
+               appendPQExpBuffer(query, "SELECT aggtransfn, "
+                                                 "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "aggmtransfn, aggminvtransfn, aggmfinalfn, "
+                                                 "aggmtranstype::pg_catalog.regtype, "
+                                                 "aggfinalextra, aggmfinalextra, "
+                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "(aggkind = 'h') AS hypothetical, "
+                                                 "aggtransspace, agginitval, "
+                                                 "aggmtransspace, aggminitval, "
+                                                 "true AS convertok, "
+                                                 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, "
+                                                 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs "
+                                         "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
+                                                 "WHERE a.aggfnoid = p.oid "
+                                                 "AND p.oid = '%u'::pg_catalog.oid",
+                                                 agginfo->aggfn.dobj.catId.oid);
+       }
+       else if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "aggsortop::pg_catalog.regoperator, "
-                                                 "agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "false AS hypothetical, "
+                                                 "0 AS aggtransspace, agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok, "
+                                                 "pg_catalog.pg_get_function_arguments(p.oid) AS funcargs, "
+                                                 "pg_catalog.pg_get_function_identity_arguments(p.oid) AS funciargs "
                                          "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                                                  "WHERE a.aggfnoid = p.oid "
                                                  "AND p.oid = '%u'::pg_catalog.oid",
                                                  agginfo->aggfn.dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70300)
+       else if (fout->remoteVersion >= 80100)
+       {
+               appendPQExpBuffer(query, "SELECT aggtransfn, "
+                                                 "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
+                                                 "aggsortop::pg_catalog.regoperator, "
+                                                 "false AS hypothetical, "
+                                                 "0 AS aggtransspace, agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
+                                                 "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
+                                                 "WHERE a.aggfnoid = p.oid "
+                                                 "AND p.oid = '%u'::pg_catalog.oid",
+                                                 agginfo->aggfn.dobj.catId.oid);
+       }
+       else if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, "
                                                  "aggfinalfn, aggtranstype::pg_catalog.regtype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "false AS hypothetical, "
+                                                 "0 AS aggtransspace, agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
                                          "FROM pg_catalog.pg_aggregate a, pg_catalog.pg_proc p "
                                                  "WHERE a.aggfnoid = p.oid "
                                                  "AND p.oid = '%u'::pg_catalog.oid",
                                                  agginfo->aggfn.dobj.catId.oid);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT aggtransfn, aggfinalfn, "
                                                  "format_type(aggtranstype, NULL) AS aggtranstype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "false AS hypothetical, "
+                                                 "0 AS aggtransspace, agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
+                                                 "true AS convertok "
                                                  "FROM pg_aggregate "
                                                  "WHERE oid = '%u'::oid",
                                                  agginfo->aggfn.dobj.catId.oid);
@@ -11010,60 +11687,93 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                appendPQExpBuffer(query, "SELECT aggtransfn1 AS aggtransfn, "
                                                  "aggfinalfn, "
                                                  "(SELECT typname FROM pg_type WHERE oid = aggtranstype1) AS aggtranstype, "
+                                                 "'-' AS aggmtransfn, '-' AS aggminvtransfn, "
+                                                 "'-' AS aggmfinalfn, 0 AS aggmtranstype, "
+                                                 "false AS aggfinalextra, false AS aggmfinalextra, "
                                                  "0 AS aggsortop, "
-                                                 "agginitval1 AS agginitval, "
+                                                 "false AS hypothetical, "
+                                                 "0 AS aggtransspace, agginitval1 AS agginitval, "
+                                                 "0 AS aggmtransspace, NULL AS aggminitval, "
                                                  "(aggtransfn2 = 0 and aggtranstype2 = 0 and agginitval2 is null) AS convertok "
                                                  "FROM pg_aggregate "
                                                  "WHERE oid = '%u'::oid",
                                                  agginfo->aggfn.dobj.catId.oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
        i_aggtransfn = PQfnumber(res, "aggtransfn");
        i_aggfinalfn = PQfnumber(res, "aggfinalfn");
+       i_aggmtransfn = PQfnumber(res, "aggmtransfn");
+       i_aggminvtransfn = PQfnumber(res, "aggminvtransfn");
+       i_aggmfinalfn = PQfnumber(res, "aggmfinalfn");
+       i_aggfinalextra = PQfnumber(res, "aggfinalextra");
+       i_aggmfinalextra = PQfnumber(res, "aggmfinalextra");
        i_aggsortop = PQfnumber(res, "aggsortop");
+       i_hypothetical = PQfnumber(res, "hypothetical");
        i_aggtranstype = PQfnumber(res, "aggtranstype");
+       i_aggtransspace = PQfnumber(res, "aggtransspace");
+       i_aggmtranstype = PQfnumber(res, "aggmtranstype");
+       i_aggmtransspace = PQfnumber(res, "aggmtransspace");
        i_agginitval = PQfnumber(res, "agginitval");
+       i_aggminitval = PQfnumber(res, "aggminitval");
        i_convertok = PQfnumber(res, "convertok");
 
        aggtransfn = PQgetvalue(res, 0, i_aggtransfn);
        aggfinalfn = PQgetvalue(res, 0, i_aggfinalfn);
+       aggmtransfn = PQgetvalue(res, 0, i_aggmtransfn);
+       aggminvtransfn = PQgetvalue(res, 0, i_aggminvtransfn);
+       aggmfinalfn = PQgetvalue(res, 0, i_aggmfinalfn);
+       aggfinalextra = (PQgetvalue(res, 0, i_aggfinalextra)[0] == 't');
+       aggmfinalextra = (PQgetvalue(res, 0, i_aggmfinalextra)[0] == 't');
        aggsortop = PQgetvalue(res, 0, i_aggsortop);
+       hypothetical = (PQgetvalue(res, 0, i_hypothetical)[0] == 't');
        aggtranstype = PQgetvalue(res, 0, i_aggtranstype);
+       aggtransspace = PQgetvalue(res, 0, i_aggtransspace);
+       aggmtranstype = PQgetvalue(res, 0, i_aggmtranstype);
+       aggmtransspace = PQgetvalue(res, 0, i_aggmtransspace);
        agginitval = PQgetvalue(res, 0, i_agginitval);
+       aggminitval = PQgetvalue(res, 0, i_aggminitval);
        convertok = (PQgetvalue(res, 0, i_convertok)[0] == 't');
 
-       aggsig = format_aggregate_signature(agginfo, fout, true);
+       if (fout->remoteVersion >= 80400)
+       {
+               /* 8.4 or later; we rely on server-side code for most of the work */
+               char       *funcargs;
+               char       *funciargs;
+
+               funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs"));
+               funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs"));
+               aggfullsig = format_function_arguments(&agginfo->aggfn, funcargs, true);
+               aggsig = format_function_arguments(&agginfo->aggfn, funciargs, true);
+       }
+       else
+               /* pre-8.4, do it ourselves */
+               aggsig = format_aggregate_signature(agginfo, fout, true);
+
        aggsig_tag = format_aggregate_signature(agginfo, fout, false);
 
        if (!convertok)
        {
                write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n",
                                  aggsig);
+
+               if (aggfullsig)
+                       free(aggfullsig);
+
+               free(aggsig);
+
                return;
        }
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                /* If using 7.3's regproc or regtype, data is already quoted */
                appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
                                                  aggtransfn,
                                                  aggtranstype);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                /* format_type quotes, regproc does not */
                appendPQExpBuffer(details, "    SFUNC = %s,\n    STYPE = %s",
@@ -11079,9 +11789,15 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                                  fmtId(aggtranstype));
        }
 
+       if (strcmp(aggtransspace, "0") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    SSPACE = %s",
+                                                 aggtransspace);
+       }
+
        if (!PQgetisnull(res, 0, i_agginitval))
        {
-               appendPQExpBuffer(details, ",\n    INITCOND = ");
+               appendPQExpBufferStr(details, ",\n    INITCOND = ");
                appendStringLiteralAH(details, agginitval, fout);
        }
 
@@ -11089,15 +11805,49 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                appendPQExpBuffer(details, ",\n    FINALFUNC = %s",
                                                  aggfinalfn);
+               if (aggfinalextra)
+                       appendPQExpBufferStr(details, ",\n    FINALFUNC_EXTRA");
+       }
+
+       if (strcmp(aggmtransfn, "-") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MSFUNC = %s,\n    MINVFUNC = %s,\n    MSTYPE = %s",
+                                                 aggmtransfn,
+                                                 aggminvtransfn,
+                                                 aggmtranstype);
+       }
+
+       if (strcmp(aggmtransspace, "0") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MSSPACE = %s",
+                                                 aggmtransspace);
+       }
+
+       if (!PQgetisnull(res, 0, i_aggminitval))
+       {
+               appendPQExpBufferStr(details, ",\n    MINITCOND = ");
+               appendStringLiteralAH(details, aggminitval, fout);
+       }
+
+       if (strcmp(aggmfinalfn, "-") != 0)
+       {
+               appendPQExpBuffer(details, ",\n    MFINALFUNC = %s",
+                                                 aggmfinalfn);
+               if (aggmfinalextra)
+                       appendPQExpBufferStr(details, ",\n    MFINALFUNC_EXTRA");
        }
 
-       aggsortop = convertOperatorReference(aggsortop);
-       if (aggsortop)
+       aggsortconvop = convertOperatorReference(fout, aggsortop);
+       if (aggsortconvop)
        {
                appendPQExpBuffer(details, ",\n    SORTOP = %s",
-                                                 aggsortop);
+                                                 aggsortconvop);
+               free(aggsortconvop);
        }
 
+       if (hypothetical)
+               appendPQExpBufferStr(details, ",\n    HYPOTHETICAL");
+
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
         */
@@ -11106,7 +11856,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                          aggsig);
 
        appendPQExpBuffer(q, "CREATE AGGREGATE %s (\n%s\n);\n",
-                                         aggsig, details->data);
+                                         aggfullsig ? aggfullsig : aggsig, details->data);
 
        appendPQExpBuffer(labelq, "AGGREGATE %s", aggsig);
 
@@ -11120,7 +11870,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                                 agginfo->aggfn.rolname,
                                 false, "AGGREGATE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                agginfo->aggfn.dobj.dependencies, agginfo->aggfn.dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Aggregate Comments */
@@ -11134,13 +11884,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        /*
         * Since there is no GRANT ON AGGREGATE syntax, we have to make the ACL
         * command look like a function's GRANT; in particular this affects the
-        * syntax for zero-argument aggregates.
+        * syntax for zero-argument aggregates and ordered-set aggregates.
         */
        free(aggsig);
        free(aggsig_tag);
 
-       aggsig = format_function_signature(&agginfo->aggfn, true);
-       aggsig_tag = format_function_signature(&agginfo->aggfn, false);
+       aggsig = format_function_signature(fout, &agginfo->aggfn, true);
+       aggsig_tag = format_function_signature(fout, &agginfo->aggfn, false);
 
        dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
                        "FUNCTION",
@@ -11149,6 +11899,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
                        agginfo->aggfn.rolname, agginfo->aggfn.proacl);
 
        free(aggsig);
+       if (aggfullsig)
+               free(aggfullsig);
        free(aggsig_tag);
 
        PQclear(res);
@@ -11180,22 +11932,22 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(prsinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, prsinfo->dobj.namespace->dobj.name);
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
                                          fmtId(prsinfo->dobj.name));
 
        appendPQExpBuffer(q, "    START = %s,\n",
-                                         convertTSFunction(prsinfo->prsstart));
+                                         convertTSFunction(fout, prsinfo->prsstart));
        appendPQExpBuffer(q, "    GETTOKEN = %s,\n",
-                                         convertTSFunction(prsinfo->prstoken));
+                                         convertTSFunction(fout, prsinfo->prstoken));
        appendPQExpBuffer(q, "    END = %s,\n",
-                                         convertTSFunction(prsinfo->prsend));
+                                         convertTSFunction(fout, prsinfo->prsend));
        if (prsinfo->prsheadline != InvalidOid)
                appendPQExpBuffer(q, "    HEADLINE = %s,\n",
-                                                 convertTSFunction(prsinfo->prsheadline));
+                                                 convertTSFunction(fout, prsinfo->prsheadline));
        appendPQExpBuffer(q, "    LEXTYPES = %s );\n",
-                                         convertTSFunction(prsinfo->prslextype));
+                                         convertTSFunction(fout, prsinfo->prslextype));
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -11218,7 +11970,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
                                 "",
                                 false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                prsinfo->dobj.dependencies, prsinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Parser Comments */
@@ -11243,7 +11995,6 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        PQExpBuffer labelq;
        PQExpBuffer query;
        PGresult   *res;
-       int                     ntups;
        char       *nspname;
        char       *tmplname;
 
@@ -11257,35 +12008,25 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        query = createPQExpBuffer();
 
        /* Fetch name and namespace of the dictionary's template */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT nspname, tmplname "
                                          "FROM pg_ts_template p, pg_namespace n "
                                          "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
                                          dictinfo->dicttemplate);
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
        nspname = PQgetvalue(res, 0, 0);
        tmplname = PQgetvalue(res, 0, 1);
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(dictinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, dictinfo->dobj.namespace->dobj.name);
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
                                          fmtId(dictinfo->dobj.name));
 
-       appendPQExpBuffer(q, "    TEMPLATE = ");
+       appendPQExpBufferStr(q, "    TEMPLATE = ");
        if (strcmp(nspname, dictinfo->dobj.namespace->dobj.name) != 0)
                appendPQExpBuffer(q, "%s.", fmtId(nspname));
-       appendPQExpBuffer(q, "%s", fmtId(tmplname));
+       appendPQExpBufferStr(q, fmtId(tmplname));
 
        PQclear(res);
 
@@ -11293,7 +12034,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        if (dictinfo->dictinitoption)
                appendPQExpBuffer(q, ",\n    %s", dictinfo->dictinitoption);
 
-       appendPQExpBuffer(q, " );\n");
+       appendPQExpBufferStr(q, " );\n");
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -11316,7 +12057,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
                                 dictinfo->rolname,
                                 false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                dictinfo->dobj.dependencies, dictinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Dictionary Comments */
@@ -11350,16 +12091,16 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
        labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(tmplinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tmplinfo->dobj.namespace->dobj.name);
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
                                          fmtId(tmplinfo->dobj.name));
 
        if (tmplinfo->tmplinit != InvalidOid)
                appendPQExpBuffer(q, "    INIT = %s,\n",
-                                                 convertTSFunction(tmplinfo->tmplinit));
+                                                 convertTSFunction(fout, tmplinfo->tmplinit));
        appendPQExpBuffer(q, "    LEXIZE = %s );\n",
-                                         convertTSFunction(tmplinfo->tmpllexize));
+                                         convertTSFunction(fout, tmplinfo->tmpllexize));
 
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
@@ -11382,7 +12123,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
                                 "",
                                 false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tmplinfo->dobj.dependencies, tmplinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Template Comments */
@@ -11424,32 +12165,22 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        query = createPQExpBuffer();
 
        /* Fetch name and namespace of the config's parser */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT nspname, prsname "
                                          "FROM pg_ts_parser p, pg_namespace n "
                                          "WHERE p.oid = '%u' AND n.oid = prsnamespace",
                                          cfginfo->cfgparser);
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
        nspname = PQgetvalue(res, 0, 0);
        prsname = PQgetvalue(res, 0, 1);
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(cfginfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, cfginfo->dobj.namespace->dobj.name);
 
        appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
                                          fmtId(cfginfo->dobj.name));
 
-       appendPQExpBuffer(q, "    PARSER = ");
+       appendPQExpBufferStr(q, "    PARSER = ");
        if (strcmp(nspname, cfginfo->dobj.namespace->dobj.name) != 0)
                appendPQExpBuffer(q, "%s.", fmtId(nspname));
        appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
@@ -11467,8 +12198,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
                                          "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
                                          cfginfo->cfgparser, cfginfo->dobj.catId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
        ntups = PQntuples(res);
 
        i_tokenname = PQfnumber(res, "tokenname");
@@ -11484,7 +12214,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
                {
                        /* starting a new token type, so start a new command */
                        if (i > 0)
-                               appendPQExpBuffer(q, ";\n");
+                               appendPQExpBufferStr(q, ";\n");
                        appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
                                                          fmtId(cfginfo->dobj.name));
                        /* tokenname needs quoting, dictname does NOT */
@@ -11496,7 +12226,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        }
 
        if (ntups > 0)
-               appendPQExpBuffer(q, ";\n");
+               appendPQExpBufferStr(q, ";\n");
 
        PQclear(res);
 
@@ -11521,7 +12251,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
                                 cfginfo->rolname,
                                 false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                cfginfo->dobj.dependencies, cfginfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump Configuration Comments */
@@ -11577,7 +12307,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
        if (strlen(fdwinfo->fdwoptions) > 0)
                appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", fdwinfo->fdwoptions);
 
-       appendPQExpBuffer(q, ";\n");
+       appendPQExpBufferStr(q, ";\n");
 
        appendPQExpBuffer(delq, "DROP FOREIGN DATA WRAPPER %s;\n",
                                          qfdwname);
@@ -11595,7 +12325,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
                                 fdwinfo->rolname,
                                 false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                fdwinfo->dobj.dependencies, fdwinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Handle the ACL */
@@ -11629,7 +12359,6 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
        PQExpBuffer labelq;
        PQExpBuffer query;
        PGresult   *res;
-       int                     ntups;
        char       *qsrvname;
        char       *fdwname;
 
@@ -11645,43 +12374,33 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
        qsrvname = pg_strdup(fmtId(srvinfo->dobj.name));
 
        /* look up the foreign-data wrapper */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
        appendPQExpBuffer(query, "SELECT fdwname "
                                          "FROM pg_foreign_data_wrapper w "
                                          "WHERE w.oid = '%u'",
                                          srvinfo->srvfdw);
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
        fdwname = PQgetvalue(res, 0, 0);
 
        appendPQExpBuffer(q, "CREATE SERVER %s", qsrvname);
        if (srvinfo->srvtype && strlen(srvinfo->srvtype) > 0)
        {
-               appendPQExpBuffer(q, " TYPE ");
+               appendPQExpBufferStr(q, " TYPE ");
                appendStringLiteralAH(q, srvinfo->srvtype, fout);
        }
        if (srvinfo->srvversion && strlen(srvinfo->srvversion) > 0)
        {
-               appendPQExpBuffer(q, " VERSION ");
+               appendPQExpBufferStr(q, " VERSION ");
                appendStringLiteralAH(q, srvinfo->srvversion, fout);
        }
 
-       appendPQExpBuffer(q, " FOREIGN DATA WRAPPER ");
-       appendPQExpBuffer(q, "%s", fmtId(fdwname));
+       appendPQExpBufferStr(q, " FOREIGN DATA WRAPPER ");
+       appendPQExpBufferStr(q, fmtId(fdwname));
 
        if (srvinfo->srvoptions && strlen(srvinfo->srvoptions) > 0)
                appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", srvinfo->srvoptions);
 
-       appendPQExpBuffer(q, ";\n");
+       appendPQExpBufferStr(q, ";\n");
 
        appendPQExpBuffer(delq, "DROP SERVER %s;\n",
                                          qsrvname);
@@ -11698,7 +12417,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
                                 srvinfo->rolname,
                                 false, "SERVER", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                srvinfo->dobj.dependencies, srvinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Handle the ACL */
@@ -11762,22 +12481,22 @@ dumpUserMappings(Archive *fout,
         * OPTIONS clause.      A possible alternative is to skip such mappings
         * altogether, but it's not clear that that's an improvement.
         */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        appendPQExpBuffer(query,
                                          "SELECT usename, "
                                          "array_to_string(ARRAY("
                                          "SELECT quote_ident(option_name) || ' ' || "
                                          "quote_literal(option_value) "
-                                         "FROM pg_options_to_table(umoptions)"
+                                         "FROM pg_options_to_table(umoptions) "
+                                         "ORDER BY option_name"
                                          "), E',\n    ') AS umoptions "
                                          "FROM pg_user_mappings "
                                          "WHERE srvid = '%u' "
                                          "ORDER BY usename",
                                          catalogId.oid);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
        i_usename = PQfnumber(res, "usename");
@@ -11798,7 +12517,7 @@ dumpUserMappings(Archive *fout,
                if (umoptions && strlen(umoptions) > 0)
                        appendPQExpBuffer(q, " OPTIONS (\n    %s\n)", umoptions);
 
-               appendPQExpBuffer(q, ";\n");
+               appendPQExpBufferStr(q, ";\n");
 
                resetPQExpBuffer(delq);
                appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
@@ -11823,6 +12542,7 @@ dumpUserMappings(Archive *fout,
 
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(delq);
+       destroyPQExpBuffer(tag);
        destroyPQExpBuffer(q);
 }
 
@@ -11854,11 +12574,14 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                case DEFACLOBJ_FUNCTION:
                        type = "FUNCTIONS";
                        break;
+               case DEFACLOBJ_TYPE:
+                       type = "TYPES";
+                       break;
                default:
                        /* shouldn't get here */
-                       write_msg(NULL, "unknown object type (%d) in default privileges\n",
-                                         (int) daclinfo->defaclobjtype);
-                       exit_nicely();
+                       exit_horribly(NULL,
+                                         "unrecognized object type in default privileges: %d\n",
+                                                 (int) daclinfo->defaclobjtype);
                        type = "";                      /* keep compiler quiet */
        }
 
@@ -11872,20 +12595,17 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                                                                 daclinfo->defaclrole,
                                                                 fout->remoteVersion,
                                                                 q))
-       {
-               write_msg(NULL, "could not parse default ACL list (%s)\n",
-                                 daclinfo->defaclacl);
-               exit_nicely();
-       }
+               exit_horribly(NULL, "could not parse default ACL list (%s)\n",
+                                         daclinfo->defaclacl);
 
        ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId,
                                 tag->data,
           daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL,
                                 NULL,
                                 daclinfo->defaclrole,
-                                false, "DEFAULT ACL", SECTION_NONE,
+                                false, "DEFAULT ACL", SECTION_POST_DATA,
                                 q->data, "", NULL,
-                                daclinfo->dobj.dependencies, daclinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        destroyPQExpBuffer(tag);
@@ -11929,11 +12649,9 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
 
        if (!buildACLCommands(name, subname, type, acls, owner,
                                                  "", fout->remoteVersion, sql))
-       {
-               write_msg(NULL, "could not parse ACL list (%s) for object \"%s\" (%s)\n",
-                                 acls, name, type);
-               exit_nicely();
-       }
+               exit_horribly(NULL,
+                                       "could not parse ACL list (%s) for object \"%s\" (%s)\n",
+                                         acls, name, type);
 
        if (sql->len > 0)
                ArchiveEntry(fout, nilCatalogId, createDumpId(),
@@ -12009,7 +12727,7 @@ dumpSecLabel(Archive *fout, const char *target,
                                                  "SECURITY LABEL FOR %s ON %s IS ",
                                                  fmtId(labels[i].provider), target);
                appendStringLiteralAH(query, labels[i].label, fout);
-               appendPQExpBuffer(query, ";\n");
+               appendPQExpBufferStr(query, ";\n");
        }
 
        if (query->len > 0)
@@ -12083,7 +12801,7 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
                appendPQExpBuffer(query, "SECURITY LABEL FOR %s ON %s IS ",
                                                  fmtId(provider), target->data);
                appendStringLiteralAH(query, label, fout);
-               appendPQExpBuffer(query, ";\n");
+               appendPQExpBufferStr(query, ";\n");
        }
        if (query->len > 0)
        {
@@ -12213,13 +12931,12 @@ collectSecLabels(Archive *fout, SecLabelItem **items)
 
        query = createPQExpBuffer();
 
-       appendPQExpBuffer(query,
-                                         "SELECT label, provider, classoid, objoid, objsubid "
-                                         "FROM pg_catalog.pg_seclabel "
-                                         "ORDER BY classoid, objoid, objsubid");
+       appendPQExpBufferStr(query,
+                                                "SELECT label, provider, classoid, objoid, objsubid "
+                                                "FROM pg_catalog.pg_seclabel "
+                                                "ORDER BY classoid, objoid, objsubid");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        /* Construct lookup table containing OIDs in numeric form */
        i_label = PQfnumber(res, "label");
@@ -12255,13 +12972,13 @@ collectSecLabels(Archive *fout, SecLabelItem **items)
 static void
 dumpTable(Archive *fout, TableInfo *tbinfo)
 {
-       if (tbinfo->dobj.dump)
+       if (tbinfo->dobj.dump && !dataOnly)
        {
                char       *namecopy;
 
                if (tbinfo->relkind == RELKIND_SEQUENCE)
                        dumpSequence(fout, tbinfo);
-               else if (!dataOnly)
+               else
                        dumpTableSchema(fout, tbinfo);
 
                /* Handle the ACL here */
@@ -12278,7 +12995,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                 * query rather than trying to fetch them during getTableAttrs, so
                 * that we won't miss ACLs on system columns.
                 */
-               if (g_fout->remoteVersion >= 80400)
+               if (fout->remoteVersion >= 80400)
                {
                        PQExpBuffer query = createPQExpBuffer();
                        PGresult   *res;
@@ -12289,8 +13006,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                                                          "WHERE attrelid = '%u' AND NOT attisdropped AND attacl IS NOT NULL "
                                                          "ORDER BY attnum",
                                                          tbinfo->dobj.catId.oid);
-                       res = PQexec(g_conn, query->data);
-                       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+                       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
                        for (i = 0; i < PQntuples(res); i++)
                        {
@@ -12300,8 +13016,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                                char       *acltag;
 
                                attnamecopy = pg_strdup(fmtId(attname));
-                               acltag = pg_malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
-                               sprintf(acltag, "%s.%s", tbinfo->dobj.name, attname);
+                               acltag = psprintf("%s.%s", tbinfo->dobj.name, attname);
                                /* Column's GRANT type is always TABLE */
                                dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
                                                namecopy, attnamecopy, acltag,
@@ -12318,6 +13033,63 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
        }
 }
 
+/*
+ * Create the AS clause for a view or materialized view. The semicolon is
+ * stripped because a materialized view must add a WITH NO DATA clause.
+ *
+ * This returns a new buffer which must be freed by the caller.
+ */
+static PQExpBuffer
+createViewAsClause(Archive *fout, TableInfo *tbinfo)
+{
+       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer result = createPQExpBuffer();
+       PGresult   *res;
+       int                     len;
+
+       /* Fetch the view definition */
+       if (fout->remoteVersion >= 70300)
+       {
+               /* Beginning in 7.3, viewname is not unique; rely on OID */
+               appendPQExpBuffer(query,
+                "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
+                                                 tbinfo->dobj.catId.oid);
+       }
+       else
+       {
+               appendPQExpBufferStr(query, "SELECT definition AS viewdef "
+                                                        "FROM pg_views WHERE viewname = ");
+               appendStringLiteralAH(query, tbinfo->dobj.name, fout);
+       }
+
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+       if (PQntuples(res) != 1)
+       {
+               if (PQntuples(res) < 1)
+                       exit_horribly(NULL, "query to obtain definition of view \"%s\" returned no data\n",
+                                                 tbinfo->dobj.name);
+               else
+                       exit_horribly(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n",
+                                                 tbinfo->dobj.name);
+       }
+
+       len = PQgetlength(res, 0, 0);
+
+       if (len == 0)
+               exit_horribly(NULL, "definition of view \"%s\" appears to be empty (length zero)\n",
+                                         tbinfo->dobj.name);
+
+       /* Strip off the trailing semicolon so that other things may follow. */
+       Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
+       appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
+
+       PQclear(res);
+       destroyPQExpBuffer(query);
+
+       return result;
+}
+
 /*
  * dumpTableSchema
  *       write the declaration (not data) of one user-defined table or view
@@ -12325,14 +13097,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
 static void
 dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 {
-       PQExpBuffer query = createPQExpBuffer();
        PQExpBuffer q = createPQExpBuffer();
        PQExpBuffer delq = createPQExpBuffer();
        PQExpBuffer labelq = createPQExpBuffer();
-       PGresult   *res;
        int                     numParents;
        TableInfo **parents;
-       int                     actual_atts;    /* number of attrs in this CREATE statment */
+       int                     actual_atts;    /* number of attrs in this CREATE statement */
        const char *reltypename;
        char       *storage;
        char       *srvname;
@@ -12341,58 +13111,19 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                k;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
        if (binary_upgrade)
-               binary_upgrade_set_type_oids_by_rel_oid(q,
+               binary_upgrade_set_type_oids_by_rel_oid(fout, q,
                                                                                                tbinfo->dobj.catId.oid);
 
        /* Is it a table or a view? */
        if (tbinfo->relkind == RELKIND_VIEW)
        {
-               char       *viewdef;
+               PQExpBuffer result;
 
                reltypename = "VIEW";
 
-               /* Fetch the view definition */
-               if (g_fout->remoteVersion >= 70300)
-               {
-                       /* Beginning in 7.3, viewname is not unique; rely on OID */
-                       appendPQExpBuffer(query,
-                                                         "SELECT pg_catalog.pg_get_viewdef('%u'::pg_catalog.oid) AS viewdef",
-                                                         tbinfo->dobj.catId.oid);
-               }
-               else
-               {
-                       appendPQExpBuffer(query, "SELECT definition AS viewdef "
-                                                         "FROM pg_views WHERE viewname = ");
-                       appendStringLiteralAH(query, tbinfo->dobj.name, fout);
-                       appendPQExpBuffer(query, ";");
-               }
-
-               res = PQexec(g_conn, query->data);
-               check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-               if (PQntuples(res) != 1)
-               {
-                       if (PQntuples(res) < 1)
-                               write_msg(NULL, "query to obtain definition of view \"%s\" returned no data\n",
-                                                 tbinfo->dobj.name);
-                       else
-                               write_msg(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n",
-                                                 tbinfo->dobj.name);
-                       exit_nicely();
-               }
-
-               viewdef = PQgetvalue(res, 0, 0);
-
-               if (strlen(viewdef) == 0)
-               {
-                       write_msg(NULL, "definition of view \"%s\" appears to be empty (length zero)\n",
-                                         tbinfo->dobj.name);
-                       exit_nicely();
-               }
-
                /*
                 * DROP must be fully qualified in case same name appears in
                 * pg_catalog
@@ -12403,62 +13134,70 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                  fmtId(tbinfo->dobj.name));
 
                if (binary_upgrade)
-                       binary_upgrade_set_pg_class_oids(q, tbinfo->dobj.catId.oid, false);
+                       binary_upgrade_set_pg_class_oids(fout, q,
+                                                                                        tbinfo->dobj.catId.oid, false);
 
                appendPQExpBuffer(q, "CREATE VIEW %s", fmtId(tbinfo->dobj.name));
                if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
                        appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
-               appendPQExpBuffer(q, " AS\n    %s\n", viewdef);
+               result = createViewAsClause(fout, tbinfo);
+               appendPQExpBuffer(q, " AS\n%s", result->data);
+               destroyPQExpBuffer(result);
+
+               if (tbinfo->checkoption != NULL)
+                       appendPQExpBuffer(q, "\n  WITH %s CHECK OPTION", tbinfo->checkoption);
+               appendPQExpBufferStr(q, ";\n");
 
                appendPQExpBuffer(labelq, "VIEW %s",
                                                  fmtId(tbinfo->dobj.name));
-
-               PQclear(res);
        }
        else
        {
-               if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
-               {
-                       int                     i_srvname;
-                       int                     i_ftoptions;
-
-                       reltypename = "FOREIGN TABLE";
-
-                       /* retrieve name of foreign server and generic options */
-                       appendPQExpBuffer(query,
-                                                         "SELECT fs.srvname, "
-                                                         "pg_catalog.array_to_string(ARRAY("
-                                                         "SELECT pg_catalog.quote_ident(option_name) || "
-                                                         "' ' || pg_catalog.quote_literal(option_value) "
-                                                         "FROM pg_catalog.pg_options_to_table(ftoptions)"
-                                                         "), E',\n    ') AS ftoptions "
-                                                         "FROM pg_catalog.pg_foreign_table ft "
-                                                         "JOIN pg_catalog.pg_foreign_server fs "
-                                                         "ON (fs.oid = ft.ftserver) "
-                                                         "WHERE ft.ftrelid = '%u'",
-                                                         tbinfo->dobj.catId.oid);
-                       res = PQexec(g_conn, query->data);
-                       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-                       if (PQntuples(res) != 1)
-                       {
-                               write_msg(NULL, ngettext("query returned %d foreign server entry for foreign table \"%s\"\n",
-                                                                                "query returned %d foreign server entries for foreign table \"%s\"\n",
-                                                                                PQntuples(res)),
-                                                 PQntuples(res), tbinfo->dobj.name);
-                               exit_nicely();
-                       }
-                       i_srvname = PQfnumber(res, "srvname");
-                       i_ftoptions = PQfnumber(res, "ftoptions");
-                       srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
-                       ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
-                       PQclear(res);
-               }
-               else
+               switch (tbinfo->relkind)
                {
-                       reltypename = "TABLE";
-                       srvname = NULL;
-                       ftoptions = NULL;
+                       case (RELKIND_FOREIGN_TABLE):
+                               {
+                                       PQExpBuffer query = createPQExpBuffer();
+                                       PGresult   *res;
+                                       int                     i_srvname;
+                                       int                     i_ftoptions;
+
+                                       reltypename = "FOREIGN TABLE";
+
+                                       /* retrieve name of foreign server and generic options */
+                                       appendPQExpBuffer(query,
+                                                                         "SELECT fs.srvname, "
+                                                                         "pg_catalog.array_to_string(ARRAY("
+                                                        "SELECT pg_catalog.quote_ident(option_name) || "
+                                                        "' ' || pg_catalog.quote_literal(option_value) "
+                                                       "FROM pg_catalog.pg_options_to_table(ftoptions) "
+                                                                         "ORDER BY option_name"
+                                                                         "), E',\n    ') AS ftoptions "
+                                                                         "FROM pg_catalog.pg_foreign_table ft "
+                                                                         "JOIN pg_catalog.pg_foreign_server fs "
+                                                                         "ON (fs.oid = ft.ftserver) "
+                                                                         "WHERE ft.ftrelid = '%u'",
+                                                                         tbinfo->dobj.catId.oid);
+                                       res = ExecuteSqlQueryForSingleRow(fout, query->data);
+                                       i_srvname = PQfnumber(res, "srvname");
+                                       i_ftoptions = PQfnumber(res, "ftoptions");
+                                       srvname = pg_strdup(PQgetvalue(res, 0, i_srvname));
+                                       ftoptions = pg_strdup(PQgetvalue(res, 0, i_ftoptions));
+                                       PQclear(res);
+                                       destroyPQExpBuffer(query);
+                                       break;
+                               }
+                       case (RELKIND_MATVIEW):
+                               reltypename = "MATERIALIZED VIEW";
+                               srvname = NULL;
+                               ftoptions = NULL;
+                               break;
+                       default:
+                               reltypename = "TABLE";
+                               srvname = NULL;
+                               ftoptions = NULL;
                }
+
                numParents = tbinfo->numParents;
                parents = tbinfo->parents;
 
@@ -12475,7 +13214,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                  fmtId(tbinfo->dobj.name));
 
                if (binary_upgrade)
-                       binary_upgrade_set_pg_class_oids(q, tbinfo->dobj.catId.oid, false);
+                       binary_upgrade_set_pg_class_oids(fout, q,
+                                                                                        tbinfo->dobj.catId.oid, false);
 
                appendPQExpBuffer(q, "CREATE %s%s %s",
                                                  tbinfo->relpersistence == RELPERSISTENCE_UNLOGGED ?
@@ -12484,185 +13224,203 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                  fmtId(tbinfo->dobj.name));
 
                /*
-                * In case of a binary upgrade, we dump the table normally and attach
-                * it to the type afterward.
+                * Attach to type, if reloftype; except in case of a binary upgrade,
+                * we dump the table normally and attach it to the type afterward.
                 */
                if (tbinfo->reloftype && !binary_upgrade)
                        appendPQExpBuffer(q, " OF %s", tbinfo->reloftype);
-               actual_atts = 0;
-               for (j = 0; j < tbinfo->numatts; j++)
+
+               if (tbinfo->relkind != RELKIND_MATVIEW)
                {
-                       /*
-                        * Normally, dump if it's one of the table's own attrs, and not
-                        * dropped.  But for binary upgrade, dump all the columns.
-                        */
-                       if ((!tbinfo->inhAttrs[j] && !tbinfo->attisdropped[j]) ||
-                               binary_upgrade)
+                       /* Dump the attributes */
+                       actual_atts = 0;
+                       for (j = 0; j < tbinfo->numatts; j++)
                        {
                                /*
-                                * Default value --- suppress if inherited (except in
-                                * binary-upgrade case, where we're not doing normal
-                                * inheritance) or if it's to be printed separately.
-                                */
-                               bool            has_default = (tbinfo->attrdefs[j] != NULL
-                                                               && (!tbinfo->inhAttrDef[j] || binary_upgrade)
-                                                                                  && !tbinfo->attrdefs[j]->separate);
-
-                               /*
-                                * Not Null constraint --- suppress if inherited, except in
-                                * binary-upgrade case.
+                                * Normally, dump if it's locally defined in this table, and
+                                * not dropped.  But for binary upgrade, we'll dump all the
+                                * columns, and then fix up the dropped and nonlocal cases
+                                * below.
                                 */
-                               bool            has_notnull = (tbinfo->notnull[j]
-                                                         && (!tbinfo->inhNotNull[j] || binary_upgrade));
-
-                               if (tbinfo->reloftype && !has_default && !has_notnull && !binary_upgrade)
-                                       continue;
-
-                               /* Format properly if not first attr */
-                               if (actual_atts == 0)
-                                       appendPQExpBuffer(q, " (");
-                               else
-                                       appendPQExpBuffer(q, ",");
-                               appendPQExpBuffer(q, "\n    ");
-                               actual_atts++;
-
-                               /* Attribute name */
-                               appendPQExpBuffer(q, "%s ",
-                                                                 fmtId(tbinfo->attnames[j]));
-
-                               if (tbinfo->attisdropped[j])
+                               if (shouldPrintColumn(tbinfo, j))
                                {
                                        /*
-                                        * ALTER TABLE DROP COLUMN clears pg_attribute.atttypid,
-                                        * so we will not have gotten a valid type name; insert
-                                        * INTEGER as a stopgap.  We'll clean things up later.
+                                        * Default value --- suppress if to be printed separately.
                                         */
-                                       appendPQExpBuffer(q, "INTEGER /* dummy */");
-                                       /* Skip all the rest, too */
-                                       continue;
-                               }
+                                       bool            has_default = (tbinfo->attrdefs[j] != NULL &&
+                                                                                        !tbinfo->attrdefs[j]->separate);
 
-                               /* Attribute type */
-                               if (tbinfo->reloftype && !binary_upgrade)
-                               {
-                                       appendPQExpBuffer(q, "WITH OPTIONS");
-                               }
-                               else if (g_fout->remoteVersion >= 70100)
-                               {
-                                       appendPQExpBuffer(q, "%s",
-                                                                         tbinfo->atttypnames[j]);
-                               }
-                               else
-                               {
-                                       /* If no format_type, fake it */
-                                       appendPQExpBuffer(q, "%s",
-                                                                         myFormatType(tbinfo->atttypnames[j],
-                                                                                                  tbinfo->atttypmod[j]));
-                               }
+                                       /*
+                                        * Not Null constraint --- suppress if inherited, except
+                                        * in binary-upgrade case where that won't work.
+                                        */
+                                       bool            has_notnull = (tbinfo->notnull[j] &&
+                                                                                          (!tbinfo->inhNotNull[j] ||
+                                                                                               binary_upgrade));
+
+                                       /* Skip column if fully defined by reloftype */
+                                       if (tbinfo->reloftype &&
+                                               !has_default && !has_notnull && !binary_upgrade)
+                                               continue;
+
+                                       /* Format properly if not first attr */
+                                       if (actual_atts == 0)
+                                               appendPQExpBufferStr(q, " (");
+                                       else
+                                               appendPQExpBufferStr(q, ",");
+                                       appendPQExpBufferStr(q, "\n    ");
+                                       actual_atts++;
 
-                               /* Add collation if not default for the type */
-                               if (OidIsValid(tbinfo->attcollation[j]))
-                               {
-                                       CollInfo   *coll;
+                                       /* Attribute name */
+                                       appendPQExpBufferStr(q, fmtId(tbinfo->attnames[j]));
+
+                                       if (tbinfo->attisdropped[j])
+                                       {
+                                               /*
+                                                * ALTER TABLE DROP COLUMN clears
+                                                * pg_attribute.atttypid, so we will not have gotten a
+                                                * valid type name; insert INTEGER as a stopgap. We'll
+                                                * clean things up later.
+                                                */
+                                               appendPQExpBufferStr(q, " INTEGER /* dummy */");
+                                               /* Skip all the rest, too */
+                                               continue;
+                                       }
+
+                                       /* Attribute type */
+                                       if (tbinfo->reloftype && !binary_upgrade)
+                                       {
+                                               appendPQExpBufferStr(q, " WITH OPTIONS");
+                                       }
+                                       else if (fout->remoteVersion >= 70100)
+                                       {
+                                               appendPQExpBuffer(q, " %s",
+                                                                                 tbinfo->atttypnames[j]);
+                                       }
+                                       else
+                                       {
+                                               /* If no format_type, fake it */
+                                               appendPQExpBuffer(q, " %s",
+                                                                                 myFormatType(tbinfo->atttypnames[j],
+                                                                                                          tbinfo->atttypmod[j]));
+                                       }
 
-                                       coll = findCollationByOid(tbinfo->attcollation[j]);
-                                       if (coll)
+                                       /* Add collation if not default for the type */
+                                       if (OidIsValid(tbinfo->attcollation[j]))
                                        {
-                                               /* always schema-qualify, don't try to be smart */
-                                               appendPQExpBuffer(q, " COLLATE %s.",
+                                               CollInfo   *coll;
+
+                                               coll = findCollationByOid(tbinfo->attcollation[j]);
+                                               if (coll)
+                                               {
+                                                       /* always schema-qualify, don't try to be smart */
+                                                       appendPQExpBuffer(q, " COLLATE %s.",
                                                                         fmtId(coll->dobj.namespace->dobj.name));
-                                               appendPQExpBuffer(q, "%s",
-                                                                                 fmtId(coll->dobj.name));
+                                                       appendPQExpBufferStr(q, fmtId(coll->dobj.name));
+                                               }
                                        }
-                               }
 
-                               if (has_default)
-                                       appendPQExpBuffer(q, " DEFAULT %s",
-                                                                         tbinfo->attrdefs[j]->adef_expr);
+                                       if (has_default)
+                                               appendPQExpBuffer(q, " DEFAULT %s",
+                                                                                 tbinfo->attrdefs[j]->adef_expr);
 
-                               if (has_notnull)
-                                       appendPQExpBuffer(q, " NOT NULL");
+                                       if (has_notnull)
+                                               appendPQExpBufferStr(q, " NOT NULL");
+                               }
                        }
-               }
 
-               /*
-                * Add non-inherited CHECK constraints, if any.
-                */
-               for (j = 0; j < tbinfo->ncheck; j++)
-               {
-                       ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
+                       /*
+                        * Add non-inherited CHECK constraints, if any.
+                        */
+                       for (j = 0; j < tbinfo->ncheck; j++)
+                       {
+                               ConstraintInfo *constr = &(tbinfo->checkexprs[j]);
 
-                       if (constr->separate || !constr->conislocal)
-                               continue;
+                               if (constr->separate || !constr->conislocal)
+                                       continue;
 
-                       if (actual_atts == 0)
-                               appendPQExpBuffer(q, " (\n    ");
-                       else
-                               appendPQExpBuffer(q, ",\n    ");
+                               if (actual_atts == 0)
+                                       appendPQExpBufferStr(q, " (\n    ");
+                               else
+                                       appendPQExpBufferStr(q, ",\n    ");
 
-                       appendPQExpBuffer(q, "CONSTRAINT %s ",
-                                                         fmtId(constr->dobj.name));
-                       appendPQExpBuffer(q, "%s", constr->condef);
+                               appendPQExpBuffer(q, "CONSTRAINT %s ",
+                                                                 fmtId(constr->dobj.name));
+                               appendPQExpBufferStr(q, constr->condef);
 
-                       actual_atts++;
-               }
+                               actual_atts++;
+                       }
 
-               if (actual_atts)
-                       appendPQExpBuffer(q, "\n)");
-               else if (!(tbinfo->reloftype && !binary_upgrade))
-               {
-                       /*
-                        * We must have a parenthesized attribute list, even though empty,
-                        * when not using the OF TYPE syntax.
-                        */
-                       appendPQExpBuffer(q, " (\n)");
-               }
+                       if (actual_atts)
+                               appendPQExpBufferStr(q, "\n)");
+                       else if (!(tbinfo->reloftype && !binary_upgrade))
+                       {
+                               /*
+                                * We must have a parenthesized attribute list, even though
+                                * empty, when not using the OF TYPE syntax.
+                                */
+                               appendPQExpBufferStr(q, " (\n)");
+                       }
 
-               if (numParents > 0 && !binary_upgrade)
-               {
-                       appendPQExpBuffer(q, "\nINHERITS (");
-                       for (k = 0; k < numParents; k++)
+                       if (numParents > 0 && !binary_upgrade)
                        {
-                               TableInfo  *parentRel = parents[k];
+                               appendPQExpBufferStr(q, "\nINHERITS (");
+                               for (k = 0; k < numParents; k++)
+                               {
+                                       TableInfo  *parentRel = parents[k];
 
-                               if (k > 0)
-                                       appendPQExpBuffer(q, ", ");
-                               if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
-                                       appendPQExpBuffer(q, "%s.",
+                                       if (k > 0)
+                                               appendPQExpBufferStr(q, ", ");
+                                       if (parentRel->dobj.namespace != tbinfo->dobj.namespace)
+                                               appendPQExpBuffer(q, "%s.",
                                                                fmtId(parentRel->dobj.namespace->dobj.name));
-                               appendPQExpBuffer(q, "%s",
-                                                                 fmtId(parentRel->dobj.name));
+                                       appendPQExpBufferStr(q, fmtId(parentRel->dobj.name));
+                               }
+                               appendPQExpBufferChar(q, ')');
                        }
-                       appendPQExpBuffer(q, ")");
-               }
 
-               if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
-                       appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
+                       if (tbinfo->relkind == RELKIND_FOREIGN_TABLE)
+                               appendPQExpBuffer(q, "\nSERVER %s", fmtId(srvname));
+               }
 
                if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) ||
                  (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0))
                {
                        bool            addcomma = false;
 
-                       appendPQExpBuffer(q, "\nWITH (");
+                       appendPQExpBufferStr(q, "\nWITH (");
                        if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
                        {
                                addcomma = true;
-                               appendPQExpBuffer(q, "%s", tbinfo->reloptions);
+                               appendPQExpBufferStr(q, tbinfo->reloptions);
                        }
                        if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)
                        {
                                appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "",
                                                                  tbinfo->toast_reloptions);
                        }
-                       appendPQExpBuffer(q, ")");
+                       appendPQExpBufferChar(q, ')');
                }
 
                /* Dump generic options if any */
                if (ftoptions && ftoptions[0])
                        appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);
 
-               appendPQExpBuffer(q, ";\n");
+               /*
+                * For materialized views, create the AS clause just like a view. At
+                * this point, we always mark the view as not populated.
+                */
+               if (tbinfo->relkind == RELKIND_MATVIEW)
+               {
+                       PQExpBuffer result;
+
+                       result = createViewAsClause(fout, tbinfo);
+                       appendPQExpBuffer(q, " AS\n%s\n  WITH NO DATA;\n",
+                                                         result->data);
+                       destroyPQExpBuffer(result);
+               }
+               else
+                       appendPQExpBufferStr(q, ";\n");
 
                /*
                 * To create binary-compatible heap files, we have to ensure the same
@@ -12677,13 +13435,14 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                 * attislocal correctly, plus fix up any inherited CHECK constraints.
                 * Analogously, we set up typed tables using ALTER TABLE / OF here.
                 */
-               if (binary_upgrade && tbinfo->relkind == RELKIND_RELATION)
+               if (binary_upgrade && (tbinfo->relkind == RELKIND_RELATION ||
+                                                          tbinfo->relkind == RELKIND_FOREIGN_TABLE) )
                {
                        for (j = 0; j < tbinfo->numatts; j++)
                        {
                                if (tbinfo->attisdropped[j])
                                {
-                                       appendPQExpBuffer(q, "\n-- For binary upgrade, recreate dropped column.\n");
+                                       appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate dropped column.\n");
                                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
                                                                          "SET attlen = %d, "
                                                                          "attalign = '%c', attbyval = false\n"
@@ -12691,25 +13450,31 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                                          tbinfo->attlen[j],
                                                                          tbinfo->attalign[j]);
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
-                                       appendPQExpBuffer(q, "\n  AND attrelid = ");
+                                       appendPQExpBufferStr(q, "\n  AND attrelid = ");
                                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
-                                       appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+                                       appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
+
+                                       if (tbinfo->relkind == RELKIND_RELATION)
+                                               appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+                                                                                 fmtId(tbinfo->dobj.name));
+                                       else
+                                               appendPQExpBuffer(q, "ALTER FOREIGN TABLE %s ",
+                                                                                 fmtId(tbinfo->dobj.name));
 
-                                       appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
-                                                                         fmtId(tbinfo->dobj.name));
                                        appendPQExpBuffer(q, "DROP COLUMN %s;\n",
                                                                          fmtId(tbinfo->attnames[j]));
                                }
                                else if (!tbinfo->attislocal[j])
                                {
-                                       appendPQExpBuffer(q, "\n-- For binary upgrade, recreate inherited column.\n");
-                                       appendPQExpBuffer(q, "UPDATE pg_catalog.pg_attribute\n"
+                                       Assert(tbinfo->relkind != RELKIND_FOREIGN_TABLE);
+                                       appendPQExpBufferStr(q, "\n-- For binary upgrade, recreate inherited column.\n");
+                                       appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_attribute\n"
                                                                          "SET attislocal = false\n"
                                                                          "WHERE attname = ");
                                        appendStringLiteralAH(q, tbinfo->attnames[j], fout);
-                                       appendPQExpBuffer(q, "\n  AND attrelid = ");
+                                       appendPQExpBufferStr(q, "\n  AND attrelid = ");
                                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
-                                       appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+                                       appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                                }
                        }
 
@@ -12720,24 +13485,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                if (constr->separate || constr->conislocal)
                                        continue;
 
-                               appendPQExpBuffer(q, "\n-- For binary upgrade, set up inherited constraint.\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n");
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                                                  fmtId(tbinfo->dobj.name));
                                appendPQExpBuffer(q, " ADD CONSTRAINT %s ",
                                                                  fmtId(constr->dobj.name));
                                appendPQExpBuffer(q, "%s;\n", constr->condef);
-                               appendPQExpBuffer(q, "UPDATE pg_catalog.pg_constraint\n"
+                               appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_constraint\n"
                                                                  "SET conislocal = false\n"
                                                                  "WHERE contype = 'c' AND conname = ");
                                appendStringLiteralAH(q, constr->dobj.name, fout);
-                               appendPQExpBuffer(q, "\n  AND conrelid = ");
+                               appendPQExpBufferStr(q, "\n  AND conrelid = ");
                                appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
-                               appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+                               appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
                        }
 
                        if (numParents > 0)
                        {
-                               appendPQExpBuffer(q, "\n-- For binary upgrade, set up inheritance this way.\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n");
                                for (k = 0; k < numParents; k++)
                                {
                                        TableInfo  *parentRel = parents[k];
@@ -12754,24 +13519,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                        if (tbinfo->reloftype)
                        {
-                               appendPQExpBuffer(q, "\n-- For binary upgrade, set up typed tables this way.\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set up typed tables this way.\n");
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s OF %s;\n",
                                                                  fmtId(tbinfo->dobj.name),
                                                                  tbinfo->reloftype);
                        }
 
-                       appendPQExpBuffer(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
+                       appendPQExpBufferStr(q, "\n-- For binary upgrade, set heap's relfrozenxid\n");
                        appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                                                          "SET relfrozenxid = '%u'\n"
                                                          "WHERE oid = ",
                                                          tbinfo->frozenxid);
                        appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
-                       appendPQExpBuffer(q, "::pg_catalog.regclass;\n");
+                       appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
 
                        if (tbinfo->toast_oid)
                        {
                                /* We preserve the toast oids, so we can use it during restore */
-                               appendPQExpBuffer(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
+                               appendPQExpBufferStr(q, "\n-- For binary upgrade, set toast's relfrozenxid\n");
                                appendPQExpBuffer(q, "UPDATE pg_catalog.pg_class\n"
                                                                  "SET relfrozenxid = '%u'\n"
                                                                  "WHERE oid = '%u';\n",
@@ -12779,16 +13544,53 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        }
                }
 
-               /* Loop dumping statistics and storage statements */
+               /*
+                * In binary_upgrade mode, restore matviews' populated status by
+                * poking pg_class directly.  This is pretty ugly, but we can't use
+                * REFRESH MATERIALIZED VIEW since it's possible that some underlying
+                * matview is not populated even though this matview is.
+                */
+               if (binary_upgrade && tbinfo->relkind == RELKIND_MATVIEW &&
+                       tbinfo->relispopulated)
+               {
+                       appendPQExpBufferStr(q, "\n-- For binary upgrade, mark materialized view as populated\n");
+                       appendPQExpBufferStr(q, "UPDATE pg_catalog.pg_class\n"
+                                                         "SET relispopulated = 't'\n"
+                                                         "WHERE oid = ");
+                       appendStringLiteralAH(q, fmtId(tbinfo->dobj.name), fout);
+                       appendPQExpBufferStr(q, "::pg_catalog.regclass;\n");
+               }
+
+               /*
+                * Dump additional per-column properties that we can't handle in the
+                * main CREATE TABLE command.
+                */
                for (j = 0; j < tbinfo->numatts; j++)
                {
+                       /* None of this applies to dropped columns */
+                       if (tbinfo->attisdropped[j])
+                               continue;
+
+                       /*
+                        * If we didn't dump the column definition explicitly above, and
+                        * it is NOT NULL and did not inherit that property from a parent,
+                        * we have to mark it separately.
+                        */
+                       if (!shouldPrintColumn(tbinfo, j) &&
+                               tbinfo->notnull[j] && !tbinfo->inhNotNull[j])
+                       {
+                               appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
+                                                                 fmtId(tbinfo->dobj.name));
+                               appendPQExpBuffer(q, "ALTER COLUMN %s SET NOT NULL;\n",
+                                                                 fmtId(tbinfo->attnames[j]));
+                       }
+
                        /*
                         * Dump per-column statistics information. We only issue an ALTER
                         * TABLE statement if the attstattarget entry for this column is
                         * non-negative (i.e. it's not the default value)
                         */
-                       if (tbinfo->attstattarget[j] >= 0 &&
-                               !tbinfo->attisdropped[j])
+                       if (tbinfo->attstattarget[j] >= 0)
                        {
                                appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                                                  fmtId(tbinfo->dobj.name));
@@ -12802,7 +13604,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                         * Dump per-column storage information.  The statement is only
                         * dumped if the storage has been changed from the type's default.
                         */
-                       if (!tbinfo->attisdropped[j] && tbinfo->attstorage[j] != tbinfo->typstorage[j])
+                       if (tbinfo->attstorage[j] != tbinfo->typstorage[j])
                        {
                                switch (tbinfo->attstorage[j])
                                {
@@ -12866,6 +13668,28 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                }
        }
 
+       /*
+        * dump properties we only have ALTER TABLE syntax for
+        */
+       if ((tbinfo->relkind == RELKIND_RELATION || tbinfo->relkind == RELKIND_MATVIEW) &&
+               tbinfo->relreplident != REPLICA_IDENTITY_DEFAULT)
+       {
+               if (tbinfo->relreplident == REPLICA_IDENTITY_INDEX)
+               {
+                       /* nothing to do, will be set when the index is dumped */
+               }
+               else if (tbinfo->relreplident == REPLICA_IDENTITY_NOTHING)
+               {
+                       appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY NOTHING;\n",
+                                                         fmtId(tbinfo->dobj.name));
+               }
+               else if (tbinfo->relreplident == REPLICA_IDENTITY_FULL)
+               {
+                       appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY FULL;\n",
+                                                         fmtId(tbinfo->dobj.name));
+               }
+       }
+
        if (binary_upgrade)
                binary_upgrade_extension_member(q, &tbinfo->dobj, labelq->data);
 
@@ -12875,9 +13699,10 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
                                 tbinfo->rolname,
                           (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
-                                reltypename, SECTION_PRE_DATA,
+                                reltypename,
+                                tbinfo->postponed_def ? SECTION_POST_DATA : SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
 
@@ -12898,7 +13723,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                dumpTableConstraintComment(fout, constr);
        }
 
-       destroyPQExpBuffer(query);
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
        destroyPQExpBuffer(labelq);
@@ -12915,18 +13739,18 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
        PQExpBuffer q;
        PQExpBuffer delq;
 
-       /* Only print it if "separate" mode is selected */
-       if (!tbinfo->dobj.dump || !adinfo->separate || dataOnly)
+       /* Skip if table definition not to be dumped */
+       if (!tbinfo->dobj.dump || dataOnly)
                return;
 
-       /* Don't print inherited defaults, either, except for binary upgrade */
-       if (tbinfo->inhAttrDef[adnum - 1] && !binary_upgrade)
+       /* Skip if not "separate"; it was dumped in the table's definition */
+       if (!adinfo->separate)
                return;
 
        q = createPQExpBuffer();
        delq = createPQExpBuffer();
 
-       appendPQExpBuffer(q, "ALTER TABLE %s ",
+       appendPQExpBuffer(q, "ALTER TABLE ONLY %s ",
                                          fmtId(tbinfo->dobj.name));
        appendPQExpBuffer(q, "ALTER COLUMN %s SET DEFAULT %s;\n",
                                          fmtId(tbinfo->attnames[adnum - 1]),
@@ -12949,7 +13773,7 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
                                 tbinfo->rolname,
                                 false, "DEFAULT", SECTION_PRE_DATA,
                                 q->data, delq->data, NULL,
-                                adinfo->dobj.dependencies, adinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        destroyPQExpBuffer(q);
@@ -12985,9 +13809,8 @@ getAttrName(int attrnum, TableInfo *tblInfo)
                case TableOidAttributeNumber:
                        return "tableoid";
        }
-       write_msg(NULL, "invalid column number %d for table \"%s\"\n",
-                         attrnum, tblInfo->dobj.name);
-       exit_nicely();
+       exit_horribly(NULL, "invalid column number %d for table \"%s\"\n",
+                                 attrnum, tblInfo->dobj.name);
        return NULL;                            /* keep compiler quiet */
 }
 
@@ -12999,6 +13822,7 @@ static void
 dumpIndex(Archive *fout, IndxInfo *indxinfo)
 {
        TableInfo  *tbinfo = indxinfo->indextable;
+       bool            is_constraint = (indxinfo->indexconstraint != 0);
        PQExpBuffer q;
        PQExpBuffer delq;
        PQExpBuffer labelq;
@@ -13016,12 +13840,15 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
        /*
         * If there's an associated constraint, don't dump the index per se, but
         * do dump any comment for it.  (This is safe because dependency ordering
-        * will have ensured the constraint is emitted first.)
+        * will have ensured the constraint is emitted first.)  Note that the
+        * emitted comment has to be shown as depending on the constraint, not
+        * the index, in such cases.
         */
-       if (indxinfo->indexconstraint == 0)
+       if (!is_constraint)
        {
                if (binary_upgrade)
-                       binary_upgrade_set_pg_class_oids(q, indxinfo->dobj.catId.oid, true);
+                       binary_upgrade_set_pg_class_oids(fout, q,
+                                                                                        indxinfo->dobj.catId.oid, true);
 
                /* Plain secondary index */
                appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef);
@@ -13035,6 +13862,15 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
                                                          fmtId(indxinfo->dobj.name));
                }
 
+               /* If the index defines identity, we need to record that. */
+               if (indxinfo->indisreplident)
+               {
+                       appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING",
+                                                         fmtId(tbinfo->dobj.name));
+                       appendPQExpBuffer(q, " INDEX %s;\n",
+                                                         fmtId(indxinfo->dobj.name));
+               }
+
                /*
                 * DROP must be fully qualified in case same name appears in
                 * pg_catalog
@@ -13051,7 +13887,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
                                         tbinfo->rolname, false,
                                         "INDEX", SECTION_POST_DATA,
                                         q->data, delq->data, NULL,
-                                        indxinfo->dobj.dependencies, indxinfo->dobj.nDeps,
+                                        NULL, 0,
                                         NULL, NULL);
        }
 
@@ -13059,7 +13895,9 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
        dumpComment(fout, labelq->data,
                                tbinfo->dobj.namespace->dobj.name,
                                tbinfo->rolname,
-                               indxinfo->dobj.catId, 0, indxinfo->dobj.dumpId);
+                               indxinfo->dobj.catId, 0,
+                               is_constraint ? indxinfo->indexconstraint :
+                               indxinfo->dobj.dumpId);
 
        destroyPQExpBuffer(q);
        destroyPQExpBuffer(delq);
@@ -13095,14 +13933,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex);
 
                if (indxinfo == NULL)
-               {
-                       write_msg(NULL, "missing index for constraint \"%s\"\n",
-                                         coninfo->dobj.name);
-                       exit_nicely();
-               }
+                       exit_horribly(NULL, "missing index for constraint \"%s\"\n",
+                                                 coninfo->dobj.name);
 
                if (binary_upgrade)
-                       binary_upgrade_set_pg_class_oids(q, indxinfo->dobj.catId.oid, true);
+                       binary_upgrade_set_pg_class_oids(fout, q,
+                                                                                        indxinfo->dobj.catId.oid, true);
 
                appendPQExpBuffer(q, "ALTER TABLE ONLY %s\n",
                                                  fmtId(tbinfo->dobj.name));
@@ -13132,19 +13968,19 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                                  fmtId(attname));
                        }
 
-                       appendPQExpBuffer(q, ")");
+                       appendPQExpBufferChar(q, ')');
 
                        if (indxinfo->options && strlen(indxinfo->options) > 0)
                                appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);
 
                        if (coninfo->condeferrable)
                        {
-                               appendPQExpBuffer(q, " DEFERRABLE");
+                               appendPQExpBufferStr(q, " DEFERRABLE");
                                if (coninfo->condeferred)
-                                       appendPQExpBuffer(q, " INITIALLY DEFERRED");
+                                       appendPQExpBufferStr(q, " INITIALLY DEFERRED");
                        }
 
-                       appendPQExpBuffer(q, ";\n");
+                       appendPQExpBufferStr(q, ";\n");
                }
 
                /* If the index is clustered, we need to record that. */
@@ -13174,7 +14010,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                         tbinfo->rolname, false,
                                         "CONSTRAINT", SECTION_POST_DATA,
                                         q->data, delq->data, NULL,
-                                        coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                                        NULL, 0,
                                         NULL, NULL);
        }
        else if (coninfo->contype == 'f')
@@ -13207,7 +14043,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                         tbinfo->rolname, false,
                                         "FK CONSTRAINT", SECTION_POST_DATA,
                                         q->data, delq->data, NULL,
-                                        coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                                        NULL, 0,
                                         NULL, NULL);
        }
        else if (coninfo->contype == 'c' && tbinfo)
@@ -13217,9 +14053,9 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                /* Ignore if not to be dumped separately */
                if (coninfo->separate)
                {
-                       /* add ONLY if we do not want it to propagate to children */
-                       appendPQExpBuffer(q, "ALTER TABLE %s %s\n",
-                                                        coninfo->conisonly ? "ONLY" : "", fmtId(tbinfo->dobj.name));
+                       /* not ONLY since we want it to propagate to children */
+                       appendPQExpBuffer(q, "ALTER TABLE %s\n",
+                                                         fmtId(tbinfo->dobj.name));
                        appendPQExpBuffer(q, "    ADD CONSTRAINT %s %s;\n",
                                                          fmtId(coninfo->dobj.name),
                                                          coninfo->condef);
@@ -13242,7 +14078,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                 tbinfo->rolname, false,
                                                 "CHECK CONSTRAINT", SECTION_POST_DATA,
                                                 q->data, delq->data, NULL,
-                                                coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                                                NULL, 0,
                                                 NULL, NULL);
                }
        }
@@ -13278,14 +14114,14 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
                                                 tyinfo->rolname, false,
                                                 "CHECK CONSTRAINT", SECTION_POST_DATA,
                                                 q->data, delq->data, NULL,
-                                                coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                                                NULL, 0,
                                                 NULL, NULL);
                }
        }
        else
        {
-               write_msg(NULL, "unrecognized constraint type: %c\n", coninfo->contype);
-               exit_nicely();
+               exit_horribly(NULL, "unrecognized constraint type: %c\n",
+                                         coninfo->contype);
        }
 
        /* Dump Constraint Comments --- only works for table constraints */
@@ -13330,31 +14166,17 @@ dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo)
  * pg_database entry for the current database
  */
 static Oid
-findLastBuiltinOid_V71(const char *dbname)
+findLastBuiltinOid_V71(Archive *fout, const char *dbname)
 {
        PGresult   *res;
-       int                     ntups;
        Oid                     last_oid;
        PQExpBuffer query = createPQExpBuffer();
 
        resetPQExpBuffer(query);
-       appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
-       appendStringLiteralAH(query, dbname, g_fout);
+       appendPQExpBufferStr(query, "SELECT datlastsysoid from pg_database where datname = ");
+       appendStringLiteralAH(query, dbname, fout);
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
-
-       ntups = PQntuples(res);
-       if (ntups < 1)
-       {
-               write_msg(NULL, "missing pg_database entry for this database\n");
-               exit_nicely();
-       }
-       if (ntups > 1)
-       {
-               write_msg(NULL, "found more than one pg_database entry for this database\n");
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
        last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid")));
        PQclear(res);
        destroyPQExpBuffer(query);
@@ -13370,62 +14192,49 @@ findLastBuiltinOid_V71(const char *dbname)
  * initdb won't be changing anymore, it'll do.
  */
 static Oid
-findLastBuiltinOid_V70(void)
+findLastBuiltinOid_V70(Archive *fout)
 {
        PGresult   *res;
-       int                     ntups;
        int                     last_oid;
 
-       res = PQexec(g_conn,
-                                "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'");
-       check_sql_result(res, g_conn,
-                                        "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'",
-                                        PGRES_TUPLES_OK);
-       ntups = PQntuples(res);
-       if (ntups < 1)
-       {
-               write_msg(NULL, "could not find entry for pg_indexes in pg_class\n");
-               exit_nicely();
-       }
-       if (ntups > 1)
-       {
-               write_msg(NULL, "found more than one entry for pg_indexes in pg_class\n");
-               exit_nicely();
-       }
+       res = ExecuteSqlQueryForSingleRow(fout,
+                                       "SELECT oid FROM pg_class WHERE relname = 'pg_indexes'");
        last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid")));
        PQclear(res);
        return last_oid;
 }
 
+/*
+ * dumpSequence
+ *       write the declaration (not data) of one user-defined sequence
+ */
 static void
 dumpSequence(Archive *fout, TableInfo *tbinfo)
 {
        PGresult   *res;
        char       *startv,
-                          *last,
                           *incby,
                           *maxv = NULL,
                           *minv = NULL,
                           *cache;
        char            bufm[100],
                                bufx[100];
-       bool            cycled,
-                               called;
+       bool            cycled;
        PQExpBuffer query = createPQExpBuffer();
        PQExpBuffer delqry = createPQExpBuffer();
        PQExpBuffer labelq = createPQExpBuffer();
 
        /* Make sure we are in proper schema */
-       selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
        snprintf(bufm, sizeof(bufm), INT64_FORMAT, SEQ_MINVALUE);
        snprintf(bufx, sizeof(bufx), INT64_FORMAT, SEQ_MAXVALUE);
 
-       if (g_fout->remoteVersion >= 80400)
+       if (fout->remoteVersion >= 80400)
        {
                appendPQExpBuffer(query,
                                                  "SELECT sequence_name, "
-                                                 "start_value, last_value, increment_by, "
+                                                 "start_value, increment_by, "
                                   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
                                   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
                                                  "     ELSE max_value "
@@ -13434,7 +14243,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                   "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
                                                  "     ELSE min_value "
                                                  "END AS min_value, "
-                                                 "cache_value, is_cycled, is_called from %s",
+                                                 "cache_value, is_cycled FROM %s",
                                                  bufx, bufm,
                                                  fmtId(tbinfo->dobj.name));
        }
@@ -13442,7 +14251,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        {
                appendPQExpBuffer(query,
                                                  "SELECT sequence_name, "
-                                                 "0 AS start_value, last_value, increment_by, "
+                                                 "0 AS start_value, increment_by, "
                                   "CASE WHEN increment_by > 0 AND max_value = %s THEN NULL "
                                   "     WHEN increment_by < 0 AND max_value = -1 THEN NULL "
                                                  "     ELSE max_value "
@@ -13451,13 +14260,12 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                   "     WHEN increment_by < 0 AND min_value = %s THEN NULL "
                                                  "     ELSE min_value "
                                                  "END AS min_value, "
-                                                 "cache_value, is_cycled, is_called from %s",
+                                                 "cache_value, is_cycled FROM %s",
                                                  bufx, bufm,
                                                  fmtId(tbinfo->dobj.name));
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        if (PQntuples(res) != 1)
        {
@@ -13465,7 +14273,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
                                                                 "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
                                                                 PQntuples(res)),
                                  tbinfo->dobj.name, PQntuples(res));
-               exit_nicely();
+               exit_nicely(1);
        }
 
        /* Disable this check: it fails if sequence has been renamed */
@@ -13474,168 +14282,125 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        {
                write_msg(NULL, "query to get data of sequence \"%s\" returned name \"%s\"\n",
                                  tbinfo->dobj.name, PQgetvalue(res, 0, 0));
-               exit_nicely();
+               exit_nicely(1);
        }
 #endif
 
        startv = PQgetvalue(res, 0, 1);
-       last = PQgetvalue(res, 0, 2);
-       incby = PQgetvalue(res, 0, 3);
+       incby = PQgetvalue(res, 0, 2);
+       if (!PQgetisnull(res, 0, 3))
+               maxv = PQgetvalue(res, 0, 3);
        if (!PQgetisnull(res, 0, 4))
-               maxv = PQgetvalue(res, 0, 4);
-       if (!PQgetisnull(res, 0, 5))
-               minv = PQgetvalue(res, 0, 5);
-       cache = PQgetvalue(res, 0, 6);
-       cycled = (strcmp(PQgetvalue(res, 0, 7), "t") == 0);
-       called = (strcmp(PQgetvalue(res, 0, 8), "t") == 0);
+               minv = PQgetvalue(res, 0, 4);
+       cache = PQgetvalue(res, 0, 5);
+       cycled = (strcmp(PQgetvalue(res, 0, 6), "t") == 0);
 
        /*
-        * The logic we use for restoring sequences is as follows:
-        *
-        * Add a CREATE SEQUENCE statement as part of a "schema" dump (use
-        * last_val for start if called is false, else use min_val for start_val).
-        * Also, if the sequence is owned by a column, add an ALTER SEQUENCE OWNED
-        * BY command for it.
-        *
-        * Add a 'SETVAL(seq, last_val, iscalled)' as part of a "data" dump.
+        * DROP must be fully qualified in case same name appears in pg_catalog
         */
-       if (!dataOnly)
-       {
-               /*
-                * DROP must be fully qualified in case same name appears in
-                * pg_catalog
-                */
-               appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
-                                                 fmtId(tbinfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(delqry, "%s;\n",
-                                                 fmtId(tbinfo->dobj.name));
+       appendPQExpBuffer(delqry, "DROP SEQUENCE %s.",
+                                         fmtId(tbinfo->dobj.namespace->dobj.name));
+       appendPQExpBuffer(delqry, "%s;\n",
+                                         fmtId(tbinfo->dobj.name));
 
-               resetPQExpBuffer(query);
+       resetPQExpBuffer(query);
 
-               if (binary_upgrade)
-               {
-                       binary_upgrade_set_pg_class_oids(query, tbinfo->dobj.catId.oid, false);
-                       binary_upgrade_set_type_oids_by_rel_oid(query, tbinfo->dobj.catId.oid);
-               }
+       if (binary_upgrade)
+       {
+               binary_upgrade_set_pg_class_oids(fout, query,
+                                                                                tbinfo->dobj.catId.oid, false);
+               binary_upgrade_set_type_oids_by_rel_oid(fout, query,
+                                                                                               tbinfo->dobj.catId.oid);
+       }
 
-               appendPQExpBuffer(query,
-                                                 "CREATE SEQUENCE %s\n",
-                                                 fmtId(tbinfo->dobj.name));
+       appendPQExpBuffer(query,
+                                         "CREATE SEQUENCE %s\n",
+                                         fmtId(tbinfo->dobj.name));
 
-               if (g_fout->remoteVersion >= 80400)
-                       appendPQExpBuffer(query, "    START WITH %s\n", startv);
-               else
-               {
-                       /*
-                        * Versions before 8.4 did not remember the true start value.  If
-                        * is_called is false then the sequence has never been incremented
-                        * so we can use last_val.      Otherwise punt and let it default.
-                        */
-                       if (!called)
-                               appendPQExpBuffer(query, "    START WITH %s\n", last);
-               }
+       if (fout->remoteVersion >= 80400)
+               appendPQExpBuffer(query, "    START WITH %s\n", startv);
 
-               appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
+       appendPQExpBuffer(query, "    INCREMENT BY %s\n", incby);
 
-               if (minv)
-                       appendPQExpBuffer(query, "    MINVALUE %s\n", minv);
-               else
-                       appendPQExpBuffer(query, "    NO MINVALUE\n");
+       if (minv)
+               appendPQExpBuffer(query, "    MINVALUE %s\n", minv);
+       else
+               appendPQExpBufferStr(query, "    NO MINVALUE\n");
 
-               if (maxv)
-                       appendPQExpBuffer(query, "    MAXVALUE %s\n", maxv);
-               else
-                       appendPQExpBuffer(query, "    NO MAXVALUE\n");
+       if (maxv)
+               appendPQExpBuffer(query, "    MAXVALUE %s\n", maxv);
+       else
+               appendPQExpBufferStr(query, "    NO MAXVALUE\n");
 
-               appendPQExpBuffer(query,
-                                                 "    CACHE %s%s",
-                                                 cache, (cycled ? "\n    CYCLE" : ""));
+       appendPQExpBuffer(query,
+                                         "    CACHE %s%s",
+                                         cache, (cycled ? "\n    CYCLE" : ""));
 
-               appendPQExpBuffer(query, ";\n");
+       appendPQExpBufferStr(query, ";\n");
 
-               appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
+       appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
 
-               /* binary_upgrade:      no need to clear TOAST table oid */
+       /* binary_upgrade:      no need to clear TOAST table oid */
 
-               if (binary_upgrade)
-                       binary_upgrade_extension_member(query, &tbinfo->dobj,
-                                                                                       labelq->data);
+       if (binary_upgrade)
+               binary_upgrade_extension_member(query, &tbinfo->dobj,
+                                                                               labelq->data);
 
-               ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
-                                        tbinfo->dobj.name,
-                                        tbinfo->dobj.namespace->dobj.name,
-                                        NULL,
-                                        tbinfo->rolname,
-                                        false, "SEQUENCE", SECTION_PRE_DATA,
-                                        query->data, delqry->data, NULL,
-                                        tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
-                                        NULL, NULL);
+       ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
+                                tbinfo->dobj.name,
+                                tbinfo->dobj.namespace->dobj.name,
+                                NULL,
+                                tbinfo->rolname,
+                                false, "SEQUENCE", SECTION_PRE_DATA,
+                                query->data, delqry->data, NULL,
+                                NULL, 0,
+                                NULL, NULL);
 
-               /*
-                * If the sequence is owned by a table column, emit the ALTER for it
-                * as a separate TOC entry immediately following the sequence's own
-                * entry.  It's OK to do this rather than using full sorting logic,
-                * because the dependency that tells us it's owned will have forced
-                * the table to be created first.  We can't just include the ALTER in
-                * the TOC entry because it will fail if we haven't reassigned the
-                * sequence owner to match the table's owner.
-                *
-                * We need not schema-qualify the table reference because both
-                * sequence and table must be in the same schema.
-                */
-               if (OidIsValid(tbinfo->owning_tab))
-               {
-                       TableInfo  *owning_tab = findTableByOid(tbinfo->owning_tab);
+       /*
+        * If the sequence is owned by a table column, emit the ALTER for it as a
+        * separate TOC entry immediately following the sequence's own entry. It's
+        * OK to do this rather than using full sorting logic, because the
+        * dependency that tells us it's owned will have forced the table to be
+        * created first.  We can't just include the ALTER in the TOC entry
+        * because it will fail if we haven't reassigned the sequence owner to
+        * match the table's owner.
+        *
+        * We need not schema-qualify the table reference because both sequence
+        * and table must be in the same schema.
+        */
+       if (OidIsValid(tbinfo->owning_tab))
+       {
+               TableInfo  *owning_tab = findTableByOid(tbinfo->owning_tab);
 
-                       if (owning_tab && owning_tab->dobj.dump)
-                       {
-                               resetPQExpBuffer(query);
-                               appendPQExpBuffer(query, "ALTER SEQUENCE %s",
-                                                                 fmtId(tbinfo->dobj.name));
-                               appendPQExpBuffer(query, " OWNED BY %s",
-                                                                 fmtId(owning_tab->dobj.name));
-                               appendPQExpBuffer(query, ".%s;\n",
+               if (owning_tab && owning_tab->dobj.dump)
+               {
+                       resetPQExpBuffer(query);
+                       appendPQExpBuffer(query, "ALTER SEQUENCE %s",
+                                                         fmtId(tbinfo->dobj.name));
+                       appendPQExpBuffer(query, " OWNED BY %s",
+                                                         fmtId(owning_tab->dobj.name));
+                       appendPQExpBuffer(query, ".%s;\n",
                                                fmtId(owning_tab->attnames[tbinfo->owning_col - 1]));
 
-                               ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                                        tbinfo->dobj.name,
-                                                        tbinfo->dobj.namespace->dobj.name,
-                                                        NULL,
-                                                        tbinfo->rolname,
-                                                        false, "SEQUENCE OWNED BY", SECTION_PRE_DATA,
-                                                        query->data, "", NULL,
-                                                        &(tbinfo->dobj.dumpId), 1,
-                                                        NULL, NULL);
-                       }
+                       ArchiveEntry(fout, nilCatalogId, createDumpId(),
+                                                tbinfo->dobj.name,
+                                                tbinfo->dobj.namespace->dobj.name,
+                                                NULL,
+                                                tbinfo->rolname,
+                                                false, "SEQUENCE OWNED BY", SECTION_PRE_DATA,
+                                                query->data, "", NULL,
+                                                &(tbinfo->dobj.dumpId), 1,
+                                                NULL, NULL);
                }
-
-               /* Dump Sequence Comments and Security Labels */
-               dumpComment(fout, labelq->data,
-                                       tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
-                                       tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
-               dumpSecLabel(fout, labelq->data,
-                                        tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
-                                        tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
        }
 
-       if (!schemaOnly)
-       {
-               resetPQExpBuffer(query);
-               appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
-               appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
-               appendPQExpBuffer(query, ", %s, %s);\n",
-                                                 last, (called ? "true" : "false"));
-
-               ArchiveEntry(fout, nilCatalogId, createDumpId(),
-                                        tbinfo->dobj.name,
-                                        tbinfo->dobj.namespace->dobj.name,
-                                        NULL,
-                                        tbinfo->rolname,
-                                        false, "SEQUENCE SET", SECTION_PRE_DATA,
-                                        query->data, "", NULL,
-                                        &(tbinfo->dobj.dumpId), 1,
-                                        NULL, NULL);
-       }
+       /* Dump Sequence Comments and Security Labels */
+       dumpComment(fout, labelq->data,
+                               tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
+                               tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
+       dumpSecLabel(fout, labelq->data,
+                                tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
+                                tbinfo->dobj.catId, 0, tbinfo->dobj.dumpId);
 
        PQclear(res);
 
@@ -13644,6 +14409,65 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        destroyPQExpBuffer(labelq);
 }
 
+/*
+ * dumpSequenceData
+ *       write the data of one user-defined sequence
+ */
+static void
+dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
+{
+       TableInfo  *tbinfo = tdinfo->tdtable;
+       PGresult   *res;
+       char       *last;
+       bool            called;
+       PQExpBuffer query = createPQExpBuffer();
+
+       /* Make sure we are in proper schema */
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
+
+       appendPQExpBuffer(query,
+                                         "SELECT last_value, is_called FROM %s",
+                                         fmtId(tbinfo->dobj.name));
+
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+
+       if (PQntuples(res) != 1)
+       {
+               write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n",
+                                                                "query to get data of sequence \"%s\" returned %d rows (expected 1)\n",
+                                                                PQntuples(res)),
+                                 tbinfo->dobj.name, PQntuples(res));
+               exit_nicely(1);
+       }
+
+       last = PQgetvalue(res, 0, 0);
+       called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
+
+       resetPQExpBuffer(query);
+       appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
+       appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
+       appendPQExpBuffer(query, ", %s, %s);\n",
+                                         last, (called ? "true" : "false"));
+
+       ArchiveEntry(fout, nilCatalogId, createDumpId(),
+                                tbinfo->dobj.name,
+                                tbinfo->dobj.namespace->dobj.name,
+                                NULL,
+                                tbinfo->rolname,
+                                false, "SEQUENCE SET", SECTION_DATA,
+                                query->data, "", NULL,
+                                &(tbinfo->dobj.dumpId), 1,
+                                NULL, NULL);
+
+       PQclear(res);
+
+       destroyPQExpBuffer(query);
+}
+
+/*
+ * dumpTrigger
+ *       write the declaration of one user-defined table trigger
+ */
 static void
 dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 {
@@ -13656,6 +14480,10 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        const char *p;
        int                     findx;
 
+       /*
+        * we needn't check dobj.dump because TriggerInfo wouldn't have been
+        * created in the first place for non-dumpable triggers
+        */
        if (dataOnly)
                return;
 
@@ -13681,57 +14509,57 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        {
                if (tginfo->tgisconstraint)
                {
-                       appendPQExpBuffer(query, "CREATE CONSTRAINT TRIGGER ");
+                       appendPQExpBufferStr(query, "CREATE CONSTRAINT TRIGGER ");
                        appendPQExpBufferStr(query, fmtId(tginfo->tgconstrname));
                }
                else
                {
-                       appendPQExpBuffer(query, "CREATE TRIGGER ");
+                       appendPQExpBufferStr(query, "CREATE TRIGGER ");
                        appendPQExpBufferStr(query, fmtId(tginfo->dobj.name));
                }
-               appendPQExpBuffer(query, "\n    ");
+               appendPQExpBufferStr(query, "\n    ");
 
                /* Trigger type */
                if (TRIGGER_FOR_BEFORE(tginfo->tgtype))
-                       appendPQExpBuffer(query, "BEFORE");
+                       appendPQExpBufferStr(query, "BEFORE");
                else if (TRIGGER_FOR_AFTER(tginfo->tgtype))
-                       appendPQExpBuffer(query, "AFTER");
+                       appendPQExpBufferStr(query, "AFTER");
                else if (TRIGGER_FOR_INSTEAD(tginfo->tgtype))
-                       appendPQExpBuffer(query, "INSTEAD OF");
+                       appendPQExpBufferStr(query, "INSTEAD OF");
                else
                {
                        write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype);
-                       exit_nicely();
+                       exit_nicely(1);
                }
 
                findx = 0;
                if (TRIGGER_FOR_INSERT(tginfo->tgtype))
                {
-                       appendPQExpBuffer(query, " INSERT");
+                       appendPQExpBufferStr(query, " INSERT");
                        findx++;
                }
                if (TRIGGER_FOR_DELETE(tginfo->tgtype))
                {
                        if (findx > 0)
-                               appendPQExpBuffer(query, " OR DELETE");
+                               appendPQExpBufferStr(query, " OR DELETE");
                        else
-                               appendPQExpBuffer(query, " DELETE");
+                               appendPQExpBufferStr(query, " DELETE");
                        findx++;
                }
                if (TRIGGER_FOR_UPDATE(tginfo->tgtype))
                {
                        if (findx > 0)
-                               appendPQExpBuffer(query, " OR UPDATE");
+                               appendPQExpBufferStr(query, " OR UPDATE");
                        else
-                               appendPQExpBuffer(query, " UPDATE");
+                               appendPQExpBufferStr(query, " UPDATE");
                        findx++;
                }
                if (TRIGGER_FOR_TRUNCATE(tginfo->tgtype))
                {
                        if (findx > 0)
-                               appendPQExpBuffer(query, " OR TRUNCATE");
+                               appendPQExpBufferStr(query, " OR TRUNCATE");
                        else
-                               appendPQExpBuffer(query, " TRUNCATE");
+                               appendPQExpBufferStr(query, " TRUNCATE");
                        findx++;
                }
                appendPQExpBuffer(query, " ON %s\n",
@@ -13742,7 +14570,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                        if (OidIsValid(tginfo->tgconstrrelid))
                        {
                                /* If we are using regclass, name is already quoted */
-                               if (g_fout->remoteVersion >= 70300)
+                               if (fout->remoteVersion >= 70300)
                                        appendPQExpBuffer(query, "    FROM %s\n    ",
                                                                          tginfo->tgconstrrelname);
                                else
@@ -13750,21 +14578,21 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                                                                          fmtId(tginfo->tgconstrrelname));
                        }
                        if (!tginfo->tgdeferrable)
-                               appendPQExpBuffer(query, "NOT ");
-                       appendPQExpBuffer(query, "DEFERRABLE INITIALLY ");
+                               appendPQExpBufferStr(query, "NOT ");
+                       appendPQExpBufferStr(query, "DEFERRABLE INITIALLY ");
                        if (tginfo->tginitdeferred)
-                               appendPQExpBuffer(query, "DEFERRED\n");
+                               appendPQExpBufferStr(query, "DEFERRED\n");
                        else
-                               appendPQExpBuffer(query, "IMMEDIATE\n");
+                               appendPQExpBufferStr(query, "IMMEDIATE\n");
                }
 
                if (TRIGGER_FOR_ROW(tginfo->tgtype))
-                       appendPQExpBuffer(query, "    FOR EACH ROW\n    ");
+                       appendPQExpBufferStr(query, "    FOR EACH ROW\n    ");
                else
-                       appendPQExpBuffer(query, "    FOR EACH STATEMENT\n    ");
+                       appendPQExpBufferStr(query, "    FOR EACH STATEMENT\n    ");
 
                /* In 7.3, result of regproc is already quoted */
-               if (g_fout->remoteVersion >= 70300)
+               if (fout->remoteVersion >= 70300)
                        appendPQExpBuffer(query, "EXECUTE PROCEDURE %s(",
                                                          tginfo->tgfname);
                else
@@ -13786,16 +14614,16 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                                                  tginfo->tgargs,
                                                  tginfo->dobj.name,
                                                  tbinfo->dobj.name);
-                               exit_nicely();
+                               exit_nicely(1);
                        }
 
                        if (findx > 0)
-                               appendPQExpBuffer(query, ", ");
+                               appendPQExpBufferStr(query, ", ");
                        appendStringLiteralAH(query, p, fout);
                        p += tlen + 1;
                }
                free(tgargs);
-               appendPQExpBuffer(query, ");\n");
+               appendPQExpBufferStr(query, ");\n");
        }
 
        if (tginfo->tgenabled != 't' && tginfo->tgenabled != 'O')
@@ -13806,16 +14634,16 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                {
                        case 'D':
                        case 'f':
-                               appendPQExpBuffer(query, "DISABLE");
+                               appendPQExpBufferStr(query, "DISABLE");
                                break;
                        case 'A':
-                               appendPQExpBuffer(query, "ENABLE ALWAYS");
+                               appendPQExpBufferStr(query, "ENABLE ALWAYS");
                                break;
                        case 'R':
-                               appendPQExpBuffer(query, "ENABLE REPLICA");
+                               appendPQExpBufferStr(query, "ENABLE REPLICA");
                                break;
                        default:
-                               appendPQExpBuffer(query, "ENABLE");
+                               appendPQExpBufferStr(query, "ENABLE");
                                break;
                }
                appendPQExpBuffer(query, " TRIGGER %s;\n",
@@ -13834,7 +14662,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                                 tbinfo->rolname, false,
                                 "TRIGGER", SECTION_POST_DATA,
                                 query->data, delqry->data, NULL,
-                                tginfo->dobj.dependencies, tginfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        dumpComment(fout, labelq->data,
@@ -13846,6 +14674,77 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
        destroyPQExpBuffer(labelq);
 }
 
+/*
+ * dumpEventTrigger
+ *       write the declaration of one user-defined event trigger
+ */
+static void
+dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
+{
+       PQExpBuffer query;
+       PQExpBuffer labelq;
+
+       /* Skip if not to be dumped */
+       if (!evtinfo->dobj.dump || dataOnly)
+               return;
+
+       query = createPQExpBuffer();
+       labelq = createPQExpBuffer();
+
+       appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
+       appendPQExpBufferStr(query, fmtId(evtinfo->dobj.name));
+       appendPQExpBufferStr(query, " ON ");
+       appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
+       appendPQExpBufferStr(query, " ");
+
+       if (strcmp("", evtinfo->evttags) != 0)
+       {
+               appendPQExpBufferStr(query, "\n         WHEN TAG IN (");
+               appendPQExpBufferStr(query, evtinfo->evttags);
+               appendPQExpBufferStr(query, ") ");
+       }
+
+       appendPQExpBufferStr(query, "\n   EXECUTE PROCEDURE ");
+       appendPQExpBufferStr(query, evtinfo->evtfname);
+       appendPQExpBufferStr(query, "();\n");
+
+       if (evtinfo->evtenabled != 'O')
+       {
+               appendPQExpBuffer(query, "\nALTER EVENT TRIGGER %s ",
+                                                 fmtId(evtinfo->dobj.name));
+               switch (evtinfo->evtenabled)
+               {
+                       case 'D':
+                               appendPQExpBufferStr(query, "DISABLE");
+                               break;
+                       case 'A':
+                               appendPQExpBufferStr(query, "ENABLE ALWAYS");
+                               break;
+                       case 'R':
+                               appendPQExpBufferStr(query, "ENABLE REPLICA");
+                               break;
+                       default:
+                               appendPQExpBufferStr(query, "ENABLE");
+                               break;
+               }
+               appendPQExpBufferStr(query, ";\n");
+       }
+       appendPQExpBuffer(labelq, "EVENT TRIGGER %s ",
+                                         fmtId(evtinfo->dobj.name));
+
+       ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
+                                evtinfo->dobj.name, NULL, NULL, evtinfo->evtowner, false,
+                                "EVENT TRIGGER", SECTION_POST_DATA,
+                                query->data, "", NULL, NULL, 0, NULL, NULL);
+
+       dumpComment(fout, labelq->data,
+                               NULL, NULL,
+                               evtinfo->dobj.catId, 0, evtinfo->dobj.dumpId);
+
+       destroyPQExpBuffer(query);
+       destroyPQExpBuffer(labelq);
+}
+
 /*
  * dumpRule
  *             Dump a rule
@@ -13874,14 +14773,14 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
        /*
         * Make sure we are in proper schema.
         */
-       selectSourceSchema(tbinfo->dobj.namespace->dobj.name);
+       selectSourceSchema(fout, tbinfo->dobj.namespace->dobj.name);
 
        query = createPQExpBuffer();
        cmd = createPQExpBuffer();
        delcmd = createPQExpBuffer();
        labelq = createPQExpBuffer();
 
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query,
                                                  "SELECT pg_catalog.pg_get_ruledef('%u'::pg_catalog.oid) AS definition",
@@ -13895,14 +14794,13 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
                                                  rinfo->dobj.name);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        if (PQntuples(res) != 1)
        {
                write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n",
                                  rinfo->dobj.name, tbinfo->dobj.name);
-               exit_nicely();
+               exit_nicely(1);
        }
 
        printfPQExpBuffer(cmd, "%s\n", PQgetvalue(res, 0, 0));
@@ -13913,10 +14811,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
         */
        if (rinfo->ev_enabled != 'O')
        {
-               appendPQExpBuffer(cmd, "ALTER TABLE %s.",
-                                                 fmtId(tbinfo->dobj.namespace->dobj.name));
-               appendPQExpBuffer(cmd, "%s ",
-                                                 fmtId(tbinfo->dobj.name));
+               appendPQExpBuffer(cmd, "ALTER TABLE %s ", fmtId(tbinfo->dobj.name));
                switch (rinfo->ev_enabled)
                {
                        case 'A':
@@ -13934,6 +14829,16 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
                }
        }
 
+       /*
+        * Apply view's reloptions when its ON SELECT rule is separate.
+        */
+       if (rinfo->reloptions && strlen(rinfo->reloptions) > 0)
+       {
+               appendPQExpBuffer(cmd, "ALTER VIEW %s SET (%s);\n",
+                                                 fmtId(tbinfo->dobj.name),
+                                                 rinfo->reloptions);
+       }
+
        /*
         * DROP must be fully qualified in case same name appears in pg_catalog
         */
@@ -13956,7 +14861,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
                                 tbinfo->rolname, false,
                                 "RULE", SECTION_POST_DATA,
                                 cmd->data, delcmd->data, NULL,
-                                rinfo->dobj.dependencies, rinfo->dobj.nDeps,
+                                NULL, 0,
                                 NULL, NULL);
 
        /* Dump rule comments */
@@ -13977,7 +14882,8 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
  * getExtensionMembership --- obtain extension membership data
  */
 void
-getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
+getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
+                                          int numExtensions)
 {
        PQExpBuffer query;
        PGresult   *res;
@@ -13995,20 +14901,19 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
                return;
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        query = createPQExpBuffer();
 
        /* refclassid constraint is redundant but may speed the search */
-       appendPQExpBuffer(query, "SELECT "
-                                         "classid, objid, refclassid, refobjid "
-                                         "FROM pg_depend "
-                                         "WHERE refclassid = 'pg_extension'::regclass "
-                                         "AND deptype = 'e' "
-                                         "ORDER BY 3,4");
+       appendPQExpBufferStr(query, "SELECT "
+                                                "classid, objid, refclassid, refobjid "
+                                                "FROM pg_depend "
+                                                "WHERE refclassid = 'pg_extension'::regclass "
+                                                "AND deptype = 'e' "
+                                                "ORDER BY 3,4");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -14094,8 +14999,9 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
         */
        for (i = 0; i < numExtensions; i++)
        {
-               char       *extconfig = extinfo[i].extconfig;
-               char       *extcondition = extinfo[i].extcondition;
+               ExtensionInfo *curext = &(extinfo[i]);
+               char       *extconfig = curext->extconfig;
+               char       *extcondition = curext->extcondition;
                char      **extconfigarray = NULL;
                char      **extconditionarray = NULL;
                int                     nconfigitems;
@@ -14110,9 +15016,42 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
                        for (j = 0; j < nconfigitems; j++)
                        {
                                TableInfo  *configtbl;
+                               Oid                     configtbloid = atooid(extconfigarray[j]);
+                               bool            dumpobj = curext->dobj.dump;
+
+                               configtbl = findTableByOid(configtbloid);
+                               if (configtbl == NULL)
+                                       continue;
 
-                               configtbl = findTableByOid(atooid(extconfigarray[j]));
-                               if (configtbl && configtbl->dataObj == NULL)
+                               /*
+                                * Tables of not-to-be-dumped extensions shouldn't be dumped
+                                * unless the table or its schema is explicitly included
+                                */
+                               if (!curext->dobj.dump)
+                               {
+                                       /* check table explicitly requested */
+                                       if (table_include_oids.head != NULL &&
+                                               simple_oid_list_member(&table_include_oids,
+                                                                                          configtbloid))
+                                               dumpobj = true;
+
+                                       /* check table's schema explicitly requested */
+                                       if (configtbl->dobj.namespace->dobj.dump)
+                                               dumpobj = true;
+                               }
+
+                               /* check table excluded by an exclusion switch */
+                               if (table_exclude_oids.head != NULL &&
+                                       simple_oid_list_member(&table_exclude_oids,
+                                                                                  configtbloid))
+                                       dumpobj = false;
+
+                               /* check schema excluded by an exclusion switch */
+                               if (simple_oid_list_member(&schema_exclude_oids,
+                                                                 configtbl->dobj.namespace->dobj.catId.oid))
+                                       dumpobj = false;
+
+                               if (dumpobj)
                                {
                                        /*
                                         * Note: config tables are dumped without OIDs regardless
@@ -14120,8 +15059,11 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
                                         * conditions aren't compatible with dumping OIDs.
                                         */
                                        makeTableDataInfo(configtbl, false);
-                                       if (strlen(extconditionarray[j]) > 0)
-                                               configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
+                                       if (configtbl->dataObj != NULL)
+                                       {
+                                               if (strlen(extconditionarray[j]) > 0)
+                                                       configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
+                                       }
                                }
                        }
                }
@@ -14138,7 +15080,7 @@ getExtensionMembership(ExtensionInfo extinfo[], int numExtensions)
  * getDependencies --- obtain available dependency data
  */
 static void
-getDependencies(void)
+getDependencies(Archive *fout)
 {
        PQExpBuffer query;
        PGresult   *res;
@@ -14153,14 +15095,14 @@ getDependencies(void)
                           *refdobj;
 
        /* No dependency info available before 7.3 */
-       if (g_fout->remoteVersion < 70300)
+       if (fout->remoteVersion < 70300)
                return;
 
        if (g_verbose)
                write_msg(NULL, "reading dependency data\n");
 
        /* Make sure we are in proper schema */
-       selectSourceSchema("pg_catalog");
+       selectSourceSchema(fout, "pg_catalog");
 
        query = createPQExpBuffer();
 
@@ -14168,14 +15110,13 @@ getDependencies(void)
         * PIN dependencies aren't interesting, and EXTENSION dependencies were
         * already processed by getExtensionMembership.
         */
-       appendPQExpBuffer(query, "SELECT "
-                                         "classid, objid, refclassid, refobjid, deptype "
-                                         "FROM pg_depend "
-                                         "WHERE deptype != 'p' AND deptype != 'e' "
-                                         "ORDER BY 1,2");
+       appendPQExpBufferStr(query, "SELECT "
+                                                "classid, objid, refclassid, refobjid, deptype "
+                                                "FROM pg_depend "
+                                                "WHERE deptype != 'p' AND deptype != 'e' "
+                                                "ORDER BY 1,2");
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
        ntups = PQntuples(res);
 
@@ -14255,6 +15196,233 @@ getDependencies(void)
 }
 
 
+/*
+ * createBoundaryObjects - create dummy DumpableObjects to represent
+ * dump section boundaries.
+ */
+static DumpableObject *
+createBoundaryObjects(void)
+{
+       DumpableObject *dobjs;
+
+       dobjs = (DumpableObject *) pg_malloc(2 * sizeof(DumpableObject));
+
+       dobjs[0].objType = DO_PRE_DATA_BOUNDARY;
+       dobjs[0].catId = nilCatalogId;
+       AssignDumpId(dobjs + 0);
+       dobjs[0].name = pg_strdup("PRE-DATA BOUNDARY");
+
+       dobjs[1].objType = DO_POST_DATA_BOUNDARY;
+       dobjs[1].catId = nilCatalogId;
+       AssignDumpId(dobjs + 1);
+       dobjs[1].name = pg_strdup("POST-DATA BOUNDARY");
+
+       return dobjs;
+}
+
+/*
+ * addBoundaryDependencies - add dependencies as needed to enforce the dump
+ * section boundaries.
+ */
+static void
+addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
+                                               DumpableObject *boundaryObjs)
+{
+       DumpableObject *preDataBound = boundaryObjs + 0;
+       DumpableObject *postDataBound = boundaryObjs + 1;
+       int                     i;
+
+       for (i = 0; i < numObjs; i++)
+       {
+               DumpableObject *dobj = dobjs[i];
+
+               /*
+                * The classification of object types here must match the SECTION_xxx
+                * values assigned during subsequent ArchiveEntry calls!
+                */
+               switch (dobj->objType)
+               {
+                       case DO_NAMESPACE:
+                       case DO_EXTENSION:
+                       case DO_TYPE:
+                       case DO_SHELL_TYPE:
+                       case DO_FUNC:
+                       case DO_AGG:
+                       case DO_OPERATOR:
+                       case DO_OPCLASS:
+                       case DO_OPFAMILY:
+                       case DO_COLLATION:
+                       case DO_CONVERSION:
+                       case DO_TABLE:
+                       case DO_ATTRDEF:
+                       case DO_PROCLANG:
+                       case DO_CAST:
+                       case DO_DUMMY_TYPE:
+                       case DO_TSPARSER:
+                       case DO_TSDICT:
+                       case DO_TSTEMPLATE:
+                       case DO_TSCONFIG:
+                       case DO_FDW:
+                       case DO_FOREIGN_SERVER:
+                       case DO_BLOB:
+                               /* Pre-data objects: must come before the pre-data boundary */
+                               addObjectDependency(preDataBound, dobj->dumpId);
+                               break;
+                       case DO_TABLE_DATA:
+                       case DO_BLOB_DATA:
+                               /* Data objects: must come between the boundaries */
+                               addObjectDependency(dobj, preDataBound->dumpId);
+                               addObjectDependency(postDataBound, dobj->dumpId);
+                               break;
+                       case DO_INDEX:
+                       case DO_REFRESH_MATVIEW:
+                       case DO_TRIGGER:
+                       case DO_EVENT_TRIGGER:
+                       case DO_DEFAULT_ACL:
+                               /* Post-data objects: must come after the post-data boundary */
+                               addObjectDependency(dobj, postDataBound->dumpId);
+                               break;
+                       case DO_RULE:
+                               /* Rules are post-data, but only if dumped separately */
+                               if (((RuleInfo *) dobj)->separate)
+                                       addObjectDependency(dobj, postDataBound->dumpId);
+                               break;
+                       case DO_CONSTRAINT:
+                       case DO_FK_CONSTRAINT:
+                               /* Constraints are post-data, but only if dumped separately */
+                               if (((ConstraintInfo *) dobj)->separate)
+                                       addObjectDependency(dobj, postDataBound->dumpId);
+                               break;
+                       case DO_PRE_DATA_BOUNDARY:
+                               /* nothing to do */
+                               break;
+                       case DO_POST_DATA_BOUNDARY:
+                               /* must come after the pre-data boundary */
+                               addObjectDependency(dobj, preDataBound->dumpId);
+                               break;
+               }
+       }
+}
+
+
+/*
+ * BuildArchiveDependencies - create dependency data for archive TOC entries
+ *
+ * The raw dependency data obtained by getDependencies() is not terribly
+ * useful in an archive dump, because in many cases there are dependency
+ * chains linking through objects that don't appear explicitly in the dump.
+ * For example, a view will depend on its _RETURN rule while the _RETURN rule
+ * will depend on other objects --- but the rule will not appear as a separate
+ * object in the dump. We need to adjust the view's dependencies to include
+ * whatever the rule depends on that is included in the dump.
+ *
+ * Just to make things more complicated, there are also "special" dependencies
+ * such as the dependency of a TABLE DATA item on its TABLE, which we must
+ * not rearrange because pg_restore knows that TABLE DATA only depends on
+ * its table.  In these cases we must leave the dependencies strictly as-is
+ * even if they refer to not-to-be-dumped objects.
+ *
+ * To handle this, the convention is that "special" dependencies are created
+ * during ArchiveEntry calls, and an archive TOC item that has any such
+ * entries will not be touched here.  Otherwise, we recursively search the
+ * DumpableObject data structures to build the correct dependencies for each
+ * archive TOC item.
+ */
+static void
+BuildArchiveDependencies(Archive *fout)
+{
+       ArchiveHandle *AH = (ArchiveHandle *) fout;
+       TocEntry   *te;
+
+       /* Scan all TOC entries in the archive */
+       for (te = AH->toc->next; te != AH->toc; te = te->next)
+       {
+               DumpableObject *dobj;
+               DumpId     *dependencies;
+               int                     nDeps;
+               int                     allocDeps;
+
+               /* No need to process entries that will not be dumped */
+               if (te->reqs == 0)
+                       continue;
+               /* Ignore entries that already have "special" dependencies */
+               if (te->nDeps > 0)
+                       continue;
+               /* Otherwise, look up the item's original DumpableObject, if any */
+               dobj = findObjectByDumpId(te->dumpId);
+               if (dobj == NULL)
+                       continue;
+               /* No work if it has no dependencies */
+               if (dobj->nDeps <= 0)
+                       continue;
+               /* Set up work array */
+               allocDeps = 64;
+               dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
+               nDeps = 0;
+               /* Recursively find all dumpable dependencies */
+               findDumpableDependencies(AH, dobj,
+                                                                &dependencies, &nDeps, &allocDeps);
+               /* And save 'em ... */
+               if (nDeps > 0)
+               {
+                       dependencies = (DumpId *) pg_realloc(dependencies,
+                                                                                                nDeps * sizeof(DumpId));
+                       te->dependencies = dependencies;
+                       te->nDeps = nDeps;
+               }
+               else
+                       free(dependencies);
+       }
+}
+
+/* Recursive search subroutine for BuildArchiveDependencies */
+static void
+findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
+                                                DumpId **dependencies, int *nDeps, int *allocDeps)
+{
+       int                     i;
+
+       /*
+        * Ignore section boundary objects: if we search through them, we'll
+        * report lots of bogus dependencies.
+        */
+       if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
+               dobj->objType == DO_POST_DATA_BOUNDARY)
+               return;
+
+       for (i = 0; i < dobj->nDeps; i++)
+       {
+               DumpId          depid = dobj->dependencies[i];
+
+               if (TocIDRequired(AH, depid) != 0)
+               {
+                       /* Object will be dumped, so just reference it as a dependency */
+                       if (*nDeps >= *allocDeps)
+                       {
+                               *allocDeps *= 2;
+                               *dependencies = (DumpId *) pg_realloc(*dependencies,
+                                                                                               *allocDeps * sizeof(DumpId));
+                       }
+                       (*dependencies)[*nDeps] = depid;
+                       (*nDeps)++;
+               }
+               else
+               {
+                       /*
+                        * Object will not be dumped, so recursively consider its deps. We
+                        * rely on the assumption that sortDumpableObjects already broke
+                        * any dependency loops, else we might recurse infinitely.
+                        */
+                       DumpableObject *otherdobj = findObjectByDumpId(depid);
+
+                       if (otherdobj)
+                               findDumpableDependencies(AH, otherdobj,
+                                                                                dependencies, nDeps, allocDeps);
+               }
+       }
+}
+
+
 /*
  * selectSourceSchema - make the specified schema the active search path
  * in the source database.
@@ -14266,35 +15434,31 @@ getDependencies(void)
  *
  * Whenever the selected schema is not pg_catalog, be careful to qualify
  * references to system catalogs and types in our emitted commands!
+ *
+ * This function is called only from selectSourceSchemaOnAH and
+ * selectSourceSchema.
  */
 static void
-selectSourceSchema(const char *schemaName)
+selectSourceSchema(Archive *fout, const char *schemaName)
 {
-       static char *curSchemaName = NULL;
        PQExpBuffer query;
 
+       /* This is checked by the callers already */
+       Assert(schemaName != NULL && *schemaName != '\0');
+
        /* Not relevant if fetching from pre-7.3 DB */
-       if (g_fout->remoteVersion < 70300)
-               return;
-       /* Ignore null schema names */
-       if (schemaName == NULL || *schemaName == '\0')
-               return;
-       /* Optimize away repeated selection of same schema */
-       if (curSchemaName && strcmp(curSchemaName, schemaName) == 0)
+       if (fout->remoteVersion < 70300)
                return;
 
        query = createPQExpBuffer();
        appendPQExpBuffer(query, "SET search_path = %s",
                                          fmtId(schemaName));
        if (strcmp(schemaName, "pg_catalog") != 0)
-               appendPQExpBuffer(query, ", pg_catalog");
+               appendPQExpBufferStr(query, ", pg_catalog");
 
-       do_sql_command(g_conn, query->data);
+       ExecuteSqlStatement(fout, query->data);
 
        destroyPQExpBuffer(query);
-       if (curSchemaName)
-               free(curSchemaName);
-       curSchemaName = pg_strdup(schemaName);
 }
 
 /*
@@ -14305,12 +15469,11 @@ selectSourceSchema(const char *schemaName)
  * schema; this is why we don't try to cache the names.
  */
 static char *
-getFormattedTypeName(Oid oid, OidOptions opts)
+getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
 {
        char       *result;
        PQExpBuffer query;
        PGresult   *res;
-       int                     ntups;
 
        if (oid == 0)
        {
@@ -14325,12 +15488,12 @@ getFormattedTypeName(Oid oid, OidOptions opts)
        }
 
        query = createPQExpBuffer();
-       if (g_fout->remoteVersion >= 70300)
+       if (fout->remoteVersion >= 70300)
        {
                appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
                                                  oid);
        }
-       else if (g_fout->remoteVersion >= 70100)
+       else if (fout->remoteVersion >= 70100)
        {
                appendPQExpBuffer(query, "SELECT format_type('%u'::oid, NULL)",
                                                  oid);
@@ -14343,21 +15506,9 @@ getFormattedTypeName(Oid oid, OidOptions opts)
                                                  oid);
        }
 
-       res = PQexec(g_conn, query->data);
-       check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+       res = ExecuteSqlQueryForSingleRow(fout, query->data);
 
-       /* Expecting a single result only */
-       ntups = PQntuples(res);
-       if (ntups != 1)
-       {
-               write_msg(NULL, ngettext("query returned %d row instead of one: %s\n",
-                                                          "query returned %d rows instead of one: %s\n",
-                                                                ntups),
-                                 ntups, query->data);
-               exit_nicely();
-       }
-
-       if (g_fout->remoteVersion >= 70100)
+       if (fout->remoteVersion >= 70100)
        {
                /* already quoted */
                result = pg_strdup(PQgetvalue(res, 0, 0));
@@ -14396,21 +15547,21 @@ myFormatType(const char *typname, int32 typmod)
        {
                int                     len = (typmod - VARHDRSZ);
 
-               appendPQExpBuffer(buf, "character");
+               appendPQExpBufferStr(buf, "character");
                if (len > 1)
                        appendPQExpBuffer(buf, "(%d)",
                                                          typmod - VARHDRSZ);
        }
        else if (strcmp(typname, "varchar") == 0)
        {
-               appendPQExpBuffer(buf, "character varying");
+               appendPQExpBufferStr(buf, "character varying");
                if (typmod != -1)
                        appendPQExpBuffer(buf, "(%d)",
                                                          typmod - VARHDRSZ);
        }
        else if (strcmp(typname, "numeric") == 0)
        {
-               appendPQExpBuffer(buf, "numeric");
+               appendPQExpBufferStr(buf, "numeric");
                if (typmod != -1)
                {
                        int32           tmp_typmod;
@@ -14430,13 +15581,13 @@ myFormatType(const char *typname, int32 typmod)
         * through with quotes. - thomas 1998-12-13
         */
        else if (strcmp(typname, "char") == 0)
-               appendPQExpBuffer(buf, "\"char\"");
+               appendPQExpBufferStr(buf, "\"char\"");
        else
-               appendPQExpBuffer(buf, "%s", fmtId(typname));
+               appendPQExpBufferStr(buf, fmtId(typname));
 
        /* Append array qualifier for array types */
        if (isarray)
-               appendPQExpBuffer(buf, "[]");
+               appendPQExpBufferStr(buf, "[]");
 
        result = pg_strdup(buf->data);
        destroyPQExpBuffer(buf);
@@ -14444,34 +15595,6 @@ myFormatType(const char *typname, int32 typmod)
        return result;
 }
 
-/*
- * fmtQualifiedId - convert a qualified name to the proper format for
- * the source database.
- *
- * Like fmtId, use the result before calling again.
- */
-static const char *
-fmtQualifiedId(const char *schema, const char *id)
-{
-       static PQExpBuffer id_return = NULL;
-
-       if (id_return)                          /* first time through? */
-               resetPQExpBuffer(id_return);
-       else
-               id_return = createPQExpBuffer();
-
-       /* Suppress schema name if fetching from pre-7.3 DB */
-       if (g_fout->remoteVersion >= 70300 && schema && *schema)
-       {
-               appendPQExpBuffer(id_return, "%s.",
-                                                 fmtId(schema));
-       }
-       appendPQExpBuffer(id_return, "%s",
-                                         fmtId(id));
-
-       return id_return->data;
-}
-
 /*
  * Return a column list clause for the given relation.
  *
@@ -14479,72 +15602,52 @@ fmtQualifiedId(const char *schema, const char *id)
  * "", not an invalid "()" column list.
  */
 static const char *
-fmtCopyColumnList(const TableInfo *ti)
+fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer)
 {
-       static PQExpBuffer q = NULL;
        int                     numatts = ti->numatts;
        char      **attnames = ti->attnames;
        bool       *attisdropped = ti->attisdropped;
        bool            needComma;
        int                     i;
 
-       if (q)                                          /* first time through? */
-               resetPQExpBuffer(q);
-       else
-               q = createPQExpBuffer();
-
-       appendPQExpBuffer(q, "(");
+       appendPQExpBufferChar(buffer, '(');
        needComma = false;
        for (i = 0; i < numatts; i++)
        {
                if (attisdropped[i])
                        continue;
                if (needComma)
-                       appendPQExpBuffer(q, ", ");
-               appendPQExpBuffer(q, "%s", fmtId(attnames[i]));
+                       appendPQExpBufferStr(buffer, ", ");
+               appendPQExpBufferStr(buffer, fmtId(attnames[i]));
                needComma = true;
        }
 
        if (!needComma)
                return "";                              /* no undropped columns */
 
-       appendPQExpBuffer(q, ")");
-       return q->data;
+       appendPQExpBufferChar(buffer, ')');
+       return buffer->data;
 }
 
 /*
- * Convenience subroutine to execute a SQL command and check for
- * COMMAND_OK status.
+ * Execute an SQL query and verify that we got exactly one row back.
  */
-static void
-do_sql_command(PGconn *conn, const char *query)
+static PGresult *
+ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
 {
        PGresult   *res;
+       int                     ntups;
 
-       res = PQexec(conn, query);
-       check_sql_result(res, conn, query, PGRES_COMMAND_OK);
-       PQclear(res);
-}
-
-/*
- * Convenience subroutine to verify a SQL command succeeded,
- * and exit with a useful error message if not.
- */
-static void
-check_sql_result(PGresult *res, PGconn *conn, const char *query,
-                                ExecStatusType expected)
-{
-       const char *err;
+       res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
 
-       if (res && PQresultStatus(res) == expected)
-               return;                                 /* A-OK */
+       /* Expecting a single result only */
+       ntups = PQntuples(res);
+       if (ntups != 1)
+               exit_horribly(NULL,
+                                         ngettext("query returned %d row instead of one: %s\n",
+                                                          "query returned %d rows instead of one: %s\n",
+                                                          ntups),
+                                         ntups, query);
 
-       write_msg(NULL, "SQL command failed\n");
-       if (res)
-               err = PQresultErrorMessage(res);
-       else
-               err = PQerrorMessage(conn);
-       write_msg(NULL, "Error message from server: %s", err);
-       write_msg(NULL, "The command was: %s\n", query);
-       exit_nicely();
+       return res;
 }