]> 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 e6c85ac0aedf11aa6f292e2823006144f78a64ca..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-2013, 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
  *
 
 #include "pg_backup_archiver.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
@@ -88,11 +86,11 @@ bool                g_verbose;                      /* User wants verbose narration of our
                                                                 * activities. */
 
 /* 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;
@@ -134,7 +132,9 @@ 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;
 
@@ -226,7 +226,8 @@ 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(FuncInfo *finfo, char *funcargs,
+                                                                          bool is_agg);
 static char *format_function_arguments_old(Archive *fout,
                                                          FuncInfo *finfo, int nallargs,
                                                          char **allargtypes,
@@ -234,17 +235,15 @@ static char *format_function_arguments_old(Archive *fout,
                                                          char **argnames);
 static char *format_function_signature(Archive *fout,
                                                  FuncInfo *finfo, bool honor_quotes);
-static const char *convertRegProcReference(Archive *fout,
+static char *convertRegProcReference(Archive *fout,
                                                const char *proc);
-static const char *convertOperatorReference(Archive *fout, const char *opr);
+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(Archive *fout,
-                          const char *schema, const char *id);
 static void getBlobs(Archive *fout);
 static void dumpBlob(Archive *fout, BlobInfo *binfo);
 static int     dumpBlobs(Archive *fout, void *arg);
@@ -262,8 +261,10 @@ 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 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
@@ -284,6 +285,7 @@ main(int argc, char **argv)
        int                     numObjs;
        DumpableObject *boundaryObjs;
        int                     i;
+       int                     numWorkers = 1;
        enum trivalue prompt_password = TRI_DEFAULT;
        int                     compressLevel = -1;
        int                     plainText = 0;
@@ -293,7 +295,6 @@ 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;
@@ -314,6 +315,7 @@ main(int argc, char **argv)
                {"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'},
@@ -344,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},
@@ -353,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}
@@ -360,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, "-- ");
@@ -390,7 +400,7 @@ main(int argc, char **argv)
                }
        }
 
-       while ((c = getopt_long(argc, argv, "abcCd:E:f:F:h:iK:n: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)
@@ -435,6 +445,10 @@ main(int argc, char **argv)
                                /* 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;
@@ -549,10 +563,16 @@ main(int argc, char **argv)
                dump_inserts = 1;
 
        if (dataOnly && schemaOnly)
-               exit_horribly(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
+       {
+               write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n");
+               exit_nicely(1);
+       }
 
        if (dataOnly && outputClean)
-               exit_horribly(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
+       {
+               write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n");
+               exit_nicely(1);
+       }
 
        if (dump_inserts && oids)
        {
@@ -561,6 +581,9 @@ main(int argc, char **argv)
                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);
 
@@ -577,8 +600,25 @@ main(int argc, char **argv)
                        compressLevel = 0;
        }
 
+       /*
+        * 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.
+        */
+       if (numWorkers <= 0
+#ifdef WIN32
+               || numWorkers > MAXIMUM_WAIT_OBJECTS
+#endif
+               )
+               exit_horribly(NULL, "%s: invalid number of parallel jobs\n", progname);
+
+       /* 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");
+
        /* Open the output file */
-       fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode);
+       fout = CreateArchive(filename, archiveFormat, compressLevel, archiveMode,
+                                                setupDumpWorker);
 
        /* Register the cleanup hook */
        on_exit_close_archive(fout);
@@ -589,16 +629,14 @@ main(int argc, char **argv)
        /* Let the archiver know how noisy to be */
        fout->verbose = g_verbose;
 
-       my_version = parse_version(PG_VERSION);
-       if (my_version < 0)
-               exit_horribly(NULL, "could not parse version string \"%s\"\n", PG_VERSION);
-
        /*
         * 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.)
         */
        fout->minRemoteVersion = 70000;
-       fout->maxRemoteVersion = (my_version / 100) * 100 + 99;
+       fout->maxRemoteVersion = (PG_VERSION_NUM / 100) * 100 + 99;
+
+       fout->numWorkers = numWorkers;
 
        /*
         * Open the database using the Archiver, so it knows about it. Errors mean
@@ -620,7 +658,8 @@ main(int argc, char **argv)
         */
        if (fout->remoteVersion >= 90000)
        {
-               PGresult *res = ExecuteSqlQueryForSingleRow(fout, "SELECT pg_catalog.pg_is_in_recovery()");
+               PGresult   *res = ExecuteSqlQueryForSingleRow(fout, "SELECT pg_catalog.pg_is_in_recovery()");
+
                if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
                {
                        /*
@@ -632,32 +671,6 @@ main(int argc, char **argv)
                PQclear(res);
        }
 
-       /*
-        * Start transaction-snapshot mode transaction to dump consistent data.
-        */
-       ExecuteSqlStatement(fout, "BEGIN");
-       if (fout->remoteVersion >= 90100)
-       {
-               if (serializable_deferrable)
-                       ExecuteSqlStatement(fout,
-                                                               "SET TRANSACTION ISOLATION LEVEL "
-                                                               "SERIALIZABLE, READ ONLY, DEFERRABLE");
-               else
-                       ExecuteSqlStatement(fout,
-                                                               "SET TRANSACTION ISOLATION LEVEL "
-                                                               "REPEATABLE READ, READ ONLY");
-       }
-       else if (fout->remoteVersion >= 70400)
-       {
-               /* note: comma was not accepted in SET TRANSACTION before 8.0 */
-               ExecuteSqlStatement(fout,
-                                                       "SET TRANSACTION ISOLATION LEVEL "
-                                                       "SERIALIZABLE READ ONLY");
-       }
-       else
-               ExecuteSqlStatement(fout,
-                                                       "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
-
        /* Select the appropriate subquery to convert user IDs to names */
        if (fout->remoteVersion >= 80100)
                username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
@@ -666,6 +679,14 @@ main(int argc, char **argv)
        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 (fout->remoteVersion < 70300)
        {
@@ -763,6 +784,10 @@ main(int argc, char **argv)
        else
                sortDumpableObjectsByTypeOid(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);
 
@@ -791,6 +816,7 @@ main(int argc, char **argv)
        ropt->dropSchema = outputClean;
        ropt->dataOnly = dataOnly;
        ropt->schemaOnly = schemaOnly;
+       ropt->if_exists = if_exists;
        ropt->dumpSections = dumpSections;
        ropt->aclsSkip = aclsSkip;
        ropt->superuser = outputSuperuser;
@@ -810,9 +836,9 @@ main(int argc, char **argv)
        SetArchiveRestoreOptions(fout, ropt);
 
        /*
-        * 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.
+        * 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);
@@ -844,6 +870,7 @@ help(const char *progname)
        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"));
@@ -871,8 +898,10 @@ help(const char *progname)
        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"));
@@ -902,7 +931,12 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
        PGconn     *conn = GetConnection(AH);
        const char *std_strings;
 
-       /* Set the client encoding if requested */
+       /*
+        * 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)
@@ -919,6 +953,10 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
        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)
        {
@@ -927,6 +965,10 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
                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 */
@@ -957,12 +999,77 @@ setup_connection(Archive *AH, const char *dumpencoding, char *use_role)
         */
        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
@@ -1029,7 +1136,7 @@ expand_schema_name_patterns(Archive *fout,
        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(GetConnection(fout), query, cell->val, false,
@@ -1073,12 +1180,12 @@ expand_table_name_patterns(Archive *fout,
        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', '%c')\n",
+                                        "\nWHERE c.relkind in ('%c', '%c', '%c', '%c', '%c')\n",
                                                  RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW,
                                                  RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE);
                processSQLNamePattern(GetConnection(fout), query, cell->val, true,
@@ -1280,6 +1387,12 @@ 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;
@@ -1304,14 +1417,14 @@ dumpTableData_copy(Archive *fout, void *dcontext)
         * cases involving ADD COLUMN and inheritance.)
         */
        if (fout->remoteVersion >= 70300)
-               column_list = fmtCopyColumnList(tbinfo);
+               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(fout,
+                                                 fmtQualifiedId(fout->remoteVersion,
                                                                                 tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  column_list);
@@ -1329,7 +1442,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
                else
                        appendPQExpBufferStr(q, "* ");
                appendPQExpBuffer(q, "FROM %s %s) TO stdout;",
-                                                 fmtQualifiedId(fout,
+                                                 fmtQualifiedId(fout->remoteVersion,
                                                                                 tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  tdinfo->filtercond);
@@ -1337,13 +1450,14 @@ dumpTableData_copy(Archive *fout, void *dcontext)
        else
        {
                appendPQExpBuffer(q, "COPY %s %s TO stdout;",
-                                                 fmtQualifiedId(fout,
+                                                 fmtQualifiedId(fout->remoteVersion,
                                                                                 tbinfo->dobj.namespace->dobj.name,
                                                                                 classname),
                                                  column_list);
        }
        res = ExecuteSqlQuery(fout, q->data, PGRES_COPY_OUT);
        PQclear(res);
+       destroyPQExpBuffer(clistBuf);
 
        for (;;)
        {
@@ -1445,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;
@@ -1462,7 +1577,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM ONLY %s",
-                                                 fmtQualifiedId(fout,
+                                                 fmtQualifiedId(fout->remoteVersion,
                                                                                 tbinfo->dobj.namespace->dobj.name,
                                                                                 classname));
        }
@@ -1470,7 +1585,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
        {
                appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR "
                                                  "SELECT * FROM %s",
-                                                 fmtQualifiedId(fout,
+                                                 fmtQualifiedId(fout->remoteVersion,
                                                                                 tbinfo->dobj.namespace->dobj.name,
                                                                                 classname));
        }
@@ -1486,34 +1601,57 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                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)
                                {
-                                       if (field > 0)
-                                               appendPQExpBuffer(q, ", ");
-                                       appendPQExpBufferStr(q, fmtId(PQfname(res, field)));
+                                       appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n");
+                               }
+                               else
+                               {
+                                       /* 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;
                                }
 
@@ -1542,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);
                                                }
@@ -1556,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:
@@ -1571,7 +1709,7 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                                                break;
                                }
                        }
-                       archprintf(fout, ");\n");
+                       archputs(");\n", fout);
                }
 
                if (PQntuples(res) <= 0)
@@ -1582,11 +1720,14 @@ dumpTableData_insert(Archive *fout, void *dcontext)
                PQclear(res);
        }
 
-       archprintf(fout, "\n\n");
+       archputs("\n\n", fout);
 
        ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor");
 
        destroyPQExpBuffer(q);
+       if (insertStmt != NULL)
+               destroyPQExpBuffer(insertStmt);
+
        return 1;
 }
 
@@ -1602,6 +1743,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
 {
        TableInfo  *tbinfo = tdinfo->tdtable;
        PQExpBuffer copyBuf = createPQExpBuffer();
+       PQExpBuffer clistBuf = createPQExpBuffer();
        DataDumperPtr dumpFn;
        char       *copyStmt;
 
@@ -1613,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;
        }
@@ -1638,6 +1780,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
                                 dumpFn, tdinfo);
 
        destroyPQExpBuffer(copyBuf);
+       destroyPQExpBuffer(clistBuf);
 }
 
 /*
@@ -1653,8 +1796,8 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
        TableInfo  *tbinfo = tdinfo->tdtable;
        PQExpBuffer q;
 
-       /* If the materialized view is not flagged as scannable, skip this. */
-       if (!tbinfo->isscannable)
+       /* If the materialized view is not flagged as populated, skip this. */
+       if (!tbinfo->relispopulated)
                return;
 
        q = createPQExpBuffer();
@@ -1663,22 +1806,22 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
                                          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 */
+                                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);
 }
@@ -1769,7 +1912,7 @@ makeTableDataInfo(TableInfo *tbinfo, bool oids)
 static void
 buildMatViewRefreshDependencies(Archive *fout)
 {
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        PGresult   *res;
        int                     ntups,
                                i;
@@ -1777,38 +1920,41 @@ buildMatViewRefreshDependencies(Archive *fout)
                                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");
 
-       if (fout->remoteVersion >= 90300)
-       {
-               appendPQExpBuffer(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'");
-       }
+       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);
 
@@ -1822,10 +1968,10 @@ buildMatViewRefreshDependencies(Archive *fout)
        {
                CatalogId       objId;
                CatalogId       refobjId;
-               DumpableObject  *dobj;
-               DumpableObject  *refdobj;
-               TableInfo          *tbinfo;
-               TableInfo          *reftbinfo;
+               DumpableObject *dobj;
+               DumpableObject *refdobj;
+               TableInfo  *tbinfo;
+               TableInfo  *reftbinfo;
 
                objId.tableoid = atooid(PQgetvalue(res, i, i_classid));
                objId.oid = atooid(PQgetvalue(res, i, i_objid));
@@ -1858,8 +2004,8 @@ buildMatViewRefreshDependencies(Archive *fout)
 
                addObjectDependency(dobj, refdobj->dumpId);
 
-               if (!reftbinfo->isscannable)
-                       tbinfo->isscannable = false;
+               if (!reftbinfo->relispopulated)
+                       tbinfo->relispopulated = false;
        }
 
        PQclear(res);
@@ -2123,33 +2269,33 @@ dumpDatabase(Archive *fout)
                                          fmtId(datname));
        if (strlen(encoding) > 0)
        {
-               appendPQExpBuffer(creaQry, " ENCODING = ");
+               appendPQExpBufferStr(creaQry, " ENCODING = ");
                appendStringLiteralAH(creaQry, encoding, fout);
        }
        if (strlen(collate) > 0)
        {
-               appendPQExpBuffer(creaQry, " LC_COLLATE = ");
+               appendPQExpBufferStr(creaQry, " LC_COLLATE = ");
                appendStringLiteralAH(creaQry, collate, fout);
        }
        if (strlen(ctype) > 0)
        {
-               appendPQExpBuffer(creaQry, " LC_CTYPE = ");
+               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, fout);
-               appendPQExpBuffer(creaQry, ";\n");
+               appendPQExpBufferStr(creaQry, ";\n");
 
        }
 
@@ -2199,7 +2345,7 @@ dumpDatabase(Archive *fout)
 
                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",
@@ -2231,7 +2377,7 @@ dumpDatabase(Archive *fout)
 
                        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",
@@ -2270,7 +2416,7 @@ dumpDatabase(Archive *fout)
                         */
                        appendPQExpBuffer(dbQry, "COMMENT ON DATABASE %s IS ", fmtId(datname));
                        appendStringLiteralAH(dbQry, comment, fout);
-                       appendPQExpBuffer(dbQry, ";\n");
+                       appendPQExpBufferStr(dbQry, ";\n");
 
                        ArchiveEntry(fout, dbCatId, createDumpId(), datname, NULL, NULL,
                                                 dba, false, "COMMENT", SECTION_NONE,
@@ -2323,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, "",
@@ -2393,13 +2539,13 @@ getBlobs(Archive *fout)
                                                  " FROM pg_largeobject_metadata",
                                                  username_subquery);
        else if (fout->remoteVersion >= 70100)
-               appendPQExpBuffer(blobQry,
-                                                 "SELECT DISTINCT loid, NULL::oid, NULL::oid"
-                                                 " FROM pg_largeobject");
+               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 = ExecuteSqlQuery(fout, blobQry->data, PGRES_TUPLES_OK);
 
@@ -2586,7 +2732,7 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
        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);
@@ -2604,7 +2750,7 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout,
 
        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",
@@ -2647,7 +2793,7 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout,
                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);
@@ -2669,22 +2815,22 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
        PQExpBuffer upgrade_query = createPQExpBuffer();
        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 = 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)
        {
@@ -2710,7 +2856,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
                        /* 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
@@ -2718,7 +2864,7 @@ binary_upgrade_set_pg_class_oids(Archive *fout,
                                                  "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);
@@ -2755,7 +2901,7 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer,
        if (extobj == NULL)
                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),
@@ -2942,10 +3088,10 @@ getExtensions(Archive *fout, int *numExtensions)
        /* Make sure we are in proper schema */
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -3465,7 +3611,7 @@ getConversions(Archive *fout, int *numConversions)
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        ConvInfo   *convinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -3480,6 +3626,8 @@ getConversions(Archive *fout, int *numConversions)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /*
         * find all conversions, including builtin conversions; we filter out
         * system-defined conversions at dump-out time.
@@ -3570,19 +3718,19 @@ getOpclasses(Archive *fout, int *numOpclasses)
        }
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -3755,7 +3903,7 @@ getAggregates(Archive *fout, int *numAggs)
                appendPQExpBuffer(query, "SELECT tableoid, oid, proname AS aggname, "
                                                  "pronamespace AS aggnamespace, "
                                                  "pronargs, proargtypes, "
-                                                 "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
+                       "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
                                                  "(%s proowner) AS rolname, "
                                                  "proacl AS aggacl "
                                                  "FROM pg_proc p "
@@ -3765,13 +3913,13 @@ getAggregates(Archive *fout, int *numAggs)
                                                  "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
                if (binary_upgrade && 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, ")");
+                       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)
        {
@@ -3948,7 +4096,7 @@ getFuncs(Archive *fout, int *numFuncs)
                                                  "SELECT tableoid, oid, proname, prolang, "
                                                  "pronargs, proargtypes, prorettype, proacl, "
                                                  "pronamespace, "
-                                                 "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
+                       "pg_catalog.pg_get_function_identity_arguments(oid) AS proiargs,"
                                                  "(%s proowner) AS rolname "
                                                  "FROM pg_proc p "
                                                  "WHERE NOT proisagg AND ("
@@ -3957,18 +4105,18 @@ getFuncs(Archive *fout, int *numFuncs)
                                                  "WHERE nspname = 'pg_catalog')",
                                                  username_subquery);
                if (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')");
+                       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)
-                       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, ")");
+                       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)
        {
@@ -4110,13 +4258,16 @@ getTables(Archive *fout, int *numTables)
        int                     i_toastoid;
        int                     i_toastfrozenxid;
        int                     i_relpersistence;
-       int                     i_isscannable;
+       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(fout, "pg_catalog");
@@ -4141,7 +4292,7 @@ getTables(Archive *fout, int *numTables)
         * we cannot correctly identify inherited columns, owned sequences, etc.
         */
 
-       if (fout->remoteVersion >= 90100)
+       if (fout->remoteVersion >= 90400)
        {
                /*
                 * Left join to pick up dependency info linking sequences to their
@@ -4155,7 +4306,86 @@ getTables(Archive *fout, int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "c.relpersistence, pg_relation_is_scannable(c.oid) as isscannable, "
+                                                 "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(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 "
+                                                 "(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 >= 90300)
+       {
+               /*
+                * 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, "
+                                                 "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(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 "
+                                                 "(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 >= 90100)
+       {
+               /*
+                * 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, "
+                                                 "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, "
@@ -4169,7 +4399,7 @@ getTables(Archive *fout, 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', '%c') "
+                                  "WHERE c.relkind in ('%c', '%c', '%c', '%c', '%c', '%c') "
                                                  "ORDER BY c.oid",
                                                  username_subquery,
                                                  RELKIND_SEQUENCE,
@@ -4191,7 +4421,8 @@ getTables(Archive *fout, int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'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, "
@@ -4226,7 +4457,8 @@ getTables(Archive *fout, int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4261,7 +4493,8 @@ getTables(Archive *fout, int *numTables)
                                                  "c.relhasindex, c.relhasrules, c.relhasoids, "
                                                  "c.relfrozenxid, tc.oid AS toid, "
                                                  "tc.relfrozenxid AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, c.relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4297,7 +4530,8 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4332,7 +4566,8 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "d.refobjid AS owning_tab, "
                                                  "d.refobjsubid AS owning_col, "
@@ -4363,7 +4598,8 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "NULL::oid AS owning_tab, "
                                                  "NULL::int4 AS owning_col, "
@@ -4389,7 +4625,8 @@ getTables(Archive *fout, int *numTables)
                                                  "0 AS relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'p' AS relpersistence, 't' as relispopulated, "
+                                                 "'d' AS relreplident, relpages, "
                                                  "NULL AS reloftype, "
                                                  "NULL::oid AS owning_tab, "
                                                  "NULL::int4 AS owning_col, "
@@ -4425,7 +4662,8 @@ getTables(Archive *fout, int *numTables)
                                                  "0 as relfrozenxid, "
                                                  "0 AS toid, "
                                                  "0 AS tfrozenxid, "
-                                                 "'p' AS relpersistence, 't'::bool as isscannable, "
+                                                 "'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, "
@@ -4473,11 +4711,14 @@ getTables(Archive *fout, int *numTables)
        i_toastoid = PQfnumber(res, "toid");
        i_toastfrozenxid = PQfnumber(res, "tfrozenxid");
        i_relpersistence = PQfnumber(res, "relpersistence");
-       i_isscannable = PQfnumber(res, "isscannable");
+       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");
 
@@ -4491,7 +4732,7 @@ getTables(Archive *fout, int *numTables)
                 * applied to other things too.
                 */
                resetPQExpBuffer(query);
-               appendPQExpBuffer(query, "SET statement_timeout = ");
+               appendPQExpBufferStr(query, "SET statement_timeout = ");
                appendStringLiteralConn(query, lockWaitTimeout, GetConnection(fout));
                ExecuteSqlStatement(fout, query->data);
        }
@@ -4515,7 +4756,9 @@ getTables(Archive *fout, 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].isscannable = (strcmp(PQgetvalue(res, i, i_isscannable), "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));
@@ -4536,6 +4779,10 @@ getTables(Archive *fout, 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 */
@@ -4549,6 +4796,8 @@ getTables(Archive *fout, 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.
@@ -4565,7 +4814,7 @@ getTables(Archive *fout, int *numTables)
                        resetPQExpBuffer(query);
                        appendPQExpBuffer(query,
                                                          "LOCK TABLE %s IN ACCESS SHARE MODE",
-                                                         fmtQualifiedId(fout,
+                                                         fmtQualifiedId(fout->remoteVersion,
                                                                                tblinfo[i].dobj.namespace->dobj.name,
                                                                                         tblinfo[i].dobj.name));
                        ExecuteSqlStatement(fout, query->data);
@@ -4647,7 +4896,7 @@ getInherits(Archive *fout, int *numInherits)
 
        /* find all the inheritance information */
 
-       appendPQExpBuffer(query, "SELECT inhrelid, inhparent FROM pg_inherits");
+       appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits");
 
        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -4696,6 +4945,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                                i_indnkeys,
                                i_indkey,
                                i_indisclustered,
+                               i_indisreplident,
                                i_contype,
                                i_conname,
                                i_condeferrable,
@@ -4704,7 +4954,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                                i_conoid,
                                i_condef,
                                i_tablespace,
-                               i_options;
+                               i_options,
+                               i_relpages;
        int                     ntups;
 
        for (i = 0; i < numTables; i++)
@@ -4741,14 +4992,50 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
                 * is not.
                 */
                resetPQExpBuffer(query);
-               if (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, "
@@ -4763,6 +5050,7 @@ getIndexes(Archive *fout, 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);
                }
@@ -4774,6 +5062,7 @@ getIndexes(Archive *fout, 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, "
@@ -4791,6 +5080,7 @@ getIndexes(Archive *fout, 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);
                }
@@ -4802,6 +5092,7 @@ getIndexes(Archive *fout, 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, "
@@ -4830,6 +5121,7 @@ getIndexes(Archive *fout, 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, "
@@ -4858,6 +5150,7 @@ getIndexes(Archive *fout, 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, "
@@ -4884,6 +5177,7 @@ getIndexes(Archive *fout, 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, "
@@ -4912,6 +5206,8 @@ getIndexes(Archive *fout, 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");
@@ -4954,6 +5250,8 @@ getIndexes(Archive *fout, 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')
@@ -5232,31 +5530,31 @@ getRules(Archive *fout, int *numRules)
 
        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 (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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -5304,7 +5602,7 @@ getRules(Archive *fout, int *numRules)
                         * table.
                         */
                        if ((ruleinfo[i].ruletable->relkind == RELKIND_VIEW ||
-                            ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
+                                ruleinfo[i].ruletable->relkind == RELKIND_MATVIEW) &&
                                ruleinfo[i].ev_type == '1' && ruleinfo[i].is_instead)
                        {
                                addObjectDependency(&ruleinfo[i].ruletable->dobj,
@@ -5573,7 +5871,7 @@ EventTriggerInfo *
 getEventTriggers(Archive *fout, int *numEventTriggers)
 {
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        PGresult   *res;
        EventTriggerInfo *evtinfo;
        int                     i_tableoid,
@@ -5593,6 +5891,8 @@ getEventTriggers(Archive *fout, int *numEventTriggers)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
        selectSourceSchema(fout, "pg_catalog");
 
@@ -5723,17 +6023,17 @@ getProcLangs(Archive *fout, int *numProcLangs)
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -5831,29 +6131,29 @@ getCasts(Archive *fout, int *numCasts)
 
        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 (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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -6553,10 +6853,10 @@ getTSParsers(Archive *fout, int *numTSParsers)
        /* Make sure we are in proper schema */
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -6722,9 +7022,9 @@ getTSTemplates(Archive *fout, int *numTSTemplates)
        /* Make sure we are in proper schema */
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -6856,7 +7156,7 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        FdwInfo    *fdwinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6874,6 +7174,8 @@ getForeignDataWrappers(Archive *fout, int *numForeignDataWrappers)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
        selectSourceSchema(fout, "pg_catalog");
 
@@ -6962,7 +7264,7 @@ getForeignServers(Archive *fout, int *numForeignServers)
        PGresult   *res;
        int                     ntups;
        int                     i;
-       PQExpBuffer query = createPQExpBuffer();
+       PQExpBuffer query;
        ForeignServerInfo *srvinfo;
        int                     i_tableoid;
        int                     i_oid;
@@ -6981,6 +7283,8 @@ getForeignServers(Archive *fout, int *numForeignServers)
                return NULL;
        }
 
+       query = createPQExpBuffer();
+
        /* Make sure we are in proper schema */
        selectSourceSchema(fout, "pg_catalog");
 
@@ -7184,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
@@ -7248,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,
@@ -7264,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,
@@ -7411,22 +7714,22 @@ 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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -7689,26 +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");
+               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'.
+                * 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);
 
-               appendPQExpBuffer(q,
+               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
@@ -7718,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++)
                {
@@ -7735,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);
@@ -7860,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)
        {
@@ -7877,7 +8180,7 @@ 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);
@@ -7886,7 +8189,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
                        appendPQExpBuffer(q, "%s ADD VALUE ",
                                                          qtypname);
                        appendStringLiteralAH(q, label, fout);
-                       appendPQExpBuffer(q, ";\n\n");
+                       appendPQExpBufferStr(q, ";\n\n");
                }
        }
 
@@ -7995,7 +8298,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
                /* 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")));
@@ -8008,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));
                }
        }
 
@@ -8021,7 +8323,7 @@ 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", qtypname);
 
@@ -8353,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
@@ -8377,41 +8679,41 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 
        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", qtypname);
 
@@ -8535,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
@@ -8566,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
@@ -8729,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)
                {
@@ -8747,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));
                                }
                        }
                }
@@ -8763,16 +9063,16 @@ 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 = ");
+                       appendPQExpBufferStr(dropped, "\n  AND attrelid = ");
                        appendStringLiteralAH(dropped, qtypname, fout);
-                       appendPQExpBuffer(dropped, "::pg_catalog.regclass;\n");
+                       appendPQExpBufferStr(dropped, "::pg_catalog.regclass;\n");
 
                        appendPQExpBuffer(dropped, "ALTER TYPE %s ",
                                                          qtypname);
@@ -8780,7 +9080,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
                                                          fmtId(attname));
                }
        }
-       appendPQExpBuffer(q, "\n);\n");
+       appendPQExpBufferStr(q, "\n);\n");
        appendPQExpBufferStr(q, dropped->data);
 
        /*
@@ -8913,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,
@@ -9109,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
@@ -9142,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);
 
@@ -9182,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;
 }
 
@@ -9261,7 +9563,7 @@ format_function_arguments_old(Archive *fout,
                                                  typname);
                free(typname);
        }
-       appendPQExpBuffer(&fn, ")");
+       appendPQExpBufferChar(&fn, ')');
        return fn.data;
 }
 
@@ -9290,15 +9592,15 @@ format_function_signature(Archive *fout, FuncInfo *finfo, bool honor_quotes)
        {
                char       *typname;
 
+               if (j > 0)
+                       appendPQExpBufferStr(&fn, ", ");
+
                typname = getFormattedTypeName(fout, finfo->argtypes[j],
                                                                           zeroAsOpaque);
-
-               appendPQExpBuffer(&fn, "%s%s",
-                                                 (j > 0) ? ", " : "",
-                                                 typname);
+               appendPQExpBufferStr(&fn, typname);
                free(typname);
        }
-       appendPQExpBuffer(&fn, ")");
+       appendPQExpBufferChar(&fn, ')');
        return fn.data;
 }
 
@@ -9317,7 +9619,7 @@ 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;
        char       *proretset;
        char       *prosrc;
@@ -9530,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
@@ -9551,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);
@@ -9621,17 +9923,14 @@ 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(fout,
                                                                                                finfo, nallargs, allargtypes,
                                                                                                argmodes, argnames);
-               funcfullsig = funcsig;
-       }
 
        funcsig_tag = format_function_signature(fout, finfo, false);
 
@@ -9642,7 +9941,8 @@ 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
@@ -9658,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)
                        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')
-               appendPQExpBuffer(q, " LEAKPROOF");
+               appendPQExpBufferStr(q, " LEAKPROOF");
 
        /*
         * COST and ROWS are emitted only if present and not default, so as not to
@@ -9722,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);
        }
@@ -9765,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);
@@ -9867,10 +10169,10 @@ dumpCast(Archive *fout, CastInfo *cast)
        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)
@@ -9894,10 +10196,10 @@ dumpCast(Archive *fout, CastInfo *cast)
        }
 
        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(fout, cast->castsource, zeroAsNone),
@@ -9959,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)
@@ -10065,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(fout, oprcode));
+       oprregproc = convertRegProcReference(fout, oprcode);
+       if (oprregproc)
+       {
+               appendPQExpBuffer(details, "    PROCEDURE = %s", oprregproc);
+               free(oprregproc);
+       }
 
        appendPQExpBuffer(oprid, "%s (",
                                          oprinfo->dobj.name);
@@ -10083,10 +10391,10 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                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)
@@ -10099,29 +10407,41 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
                appendPQExpBuffer(oprid, ", %s)", name);
        }
        else
-               appendPQExpBuffer(oprid, ", NONE)");
+               appendPQExpBufferStr(oprid, ", NONE)");
 
-       name = convertOperatorReference(fout, 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(fout, 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(fout, 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(fout, 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
@@ -10166,12 +10486,13 @@ 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 *
+static char *
 convertRegProcReference(Archive *fout, const char *proc)
 {
        /* In all cases "-" means a null reference */
@@ -10201,20 +10522,21 @@ convertRegProcReference(Archive *fout, 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 *
+static char *
 convertOperatorReference(Archive *fout, const char *opr)
 {
        OprInfo    *oprInfo;
@@ -10250,8 +10572,7 @@ convertOperatorReference(Archive *fout, 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;
        }
@@ -10263,7 +10584,7 @@ convertOperatorReference(Archive *fout, const char *opr)
                                  opr);
                return NULL;
        }
-       return oprInfo->dobj.name;
+       return pg_strdup(oprInfo->dobj.name);
 }
 
 /*
@@ -10423,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));
@@ -10431,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;
 
@@ -10543,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;
        }
@@ -10621,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);
 
@@ -10635,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));
@@ -10901,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;
                }
@@ -10938,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,
@@ -10947,7 +11268,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
                        needComma = true;
                }
 
-               appendPQExpBuffer(q, ";\n");
+               appendPQExpBufferStr(q, ";\n");
        }
 
        appendPQExpBuffer(labelq, "OPERATOR FAMILY %s",
@@ -11038,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));
 
@@ -11136,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);
@@ -11183,16 +11504,15 @@ 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;
@@ -11205,7 +11525,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes)
                                                          typname);
                        free(typname);
                }
-               appendPQExpBuffer(&buf, ")");
+               appendPQExpBufferChar(&buf, ')');
        }
        return buf.data;
 }
@@ -11222,20 +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                     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 */
@@ -11252,25 +11594,73 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        selectSourceSchema(fout, agginfo->aggfn.dobj.namespace->dobj.name);
 
        /* Get aggregate-specific details */
-       if (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, "
-                                                 "agginitval, "
-                                                 "'t'::boolean AS convertok "
+                                                 "(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, "
+                                                 "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 (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",
@@ -11280,9 +11670,14 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
        {
                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);
@@ -11292,8 +11687,13 @@ 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",
@@ -11304,25 +11704,65 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 
        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;
        }
 
@@ -11349,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);
        }
 
@@ -11359,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);
        }
 
-       aggsortop = convertOperatorReference(fout, aggsortop);
-       if (aggsortop)
+       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");
+       }
+
+       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
         */
@@ -11376,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);
 
@@ -11404,7 +11884,7 @@ 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);
@@ -11419,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);
@@ -11541,10 +12023,10 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
        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);
 
@@ -11552,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
@@ -11698,7 +12180,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        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));
@@ -11732,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 */
@@ -11744,7 +12226,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
        }
 
        if (ntups > 0)
-               appendPQExpBuffer(q, ";\n");
+               appendPQExpBufferStr(q, ";\n");
 
        PQclear(res);
 
@@ -11825,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);
@@ -11903,22 +12385,22 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
        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);
@@ -12035,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));
@@ -12060,6 +12542,7 @@ dumpUserMappings(Archive *fout,
 
        destroyPQExpBuffer(query);
        destroyPQExpBuffer(delq);
+       destroyPQExpBuffer(tag);
        destroyPQExpBuffer(q);
 }
 
@@ -12097,7 +12580,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
                default:
                        /* shouldn't get here */
                        exit_horribly(NULL,
-                                                 "unrecognized object type in default privileges: %d\n",
+                                         "unrecognized object type in default privileges: %d\n",
                                                  (int) daclinfo->defaclobjtype);
                        type = "";                      /* keep compiler quiet */
        }
@@ -12244,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)
@@ -12318,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)
        {
@@ -12448,10 +12931,10 @@ 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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -12533,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,
@@ -12570,15 +13052,14 @@ createViewAsClause(Archive *fout, TableInfo *tbinfo)
        {
                /* 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",
+                "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 = ");
+               appendPQExpBufferStr(query, "SELECT definition AS viewdef "
+                                                        "FROM pg_views WHERE viewname = ");
                appendStringLiteralAH(query, tbinfo->dobj.name, fout);
-               appendPQExpBuffer(query, ";");
        }
 
        res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
@@ -12600,7 +13081,7 @@ createViewAsClause(Archive *fout, TableInfo *tbinfo)
                                          tbinfo->dobj.name);
 
        /* Strip off the trailing semicolon so that other things may follow. */
-       Assert(PQgetvalue(res, 0, 0)[len-1] == ';');
+       Assert(PQgetvalue(res, 0, 0)[len - 1] == ';');
        appendBinaryPQExpBuffer(result, PQgetvalue(res, 0, 0), len - 1);
 
        PQclear(res);
@@ -12660,9 +13141,13 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
                        appendPQExpBuffer(q, " WITH (%s)", tbinfo->reloptions);
                result = createViewAsClause(fout, tbinfo);
-               appendPQExpBuffer(q, " AS\n%s;\n", result->data);
+               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));
        }
@@ -12671,37 +13156,37 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                switch (tbinfo->relkind)
                {
                        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;
-                       }
+                               {
+                                       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;
@@ -12747,156 +13232,155 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 
                if (tbinfo->relkind != RELKIND_MATVIEW)
                {
-               /* Dump the attributes */
-               actual_atts = 0;
-               for (j = 0; j < tbinfo->numatts; j++)
-               {
-                       /*
-                        * 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.
-                        */
-                       if (shouldPrintColumn(tbinfo, j))
+                       /* Dump the attributes */
+                       actual_atts = 0;
+                       for (j = 0; j < tbinfo->numatts; j++)
                        {
                                /*
-                                * Default value --- suppress if to be printed separately.
+                                * 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_default = (tbinfo->attrdefs[j] != NULL &&
-                                                                                  !tbinfo->attrdefs[j]->separate);
-
-                               /*
-                                * 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)
-                                       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 (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) ||
@@ -12904,18 +13388,18 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                {
                        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 */
@@ -12923,7 +13407,8 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        appendPQExpBuffer(q, "\nOPTIONS (\n    %s\n)", ftoptions);
 
                /*
-                * For materialized views, create the AS clause just like a view.
+                * 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)
                {
@@ -12935,7 +13420,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        destroyPQExpBuffer(result);
                }
                else
-                       appendPQExpBuffer(q, ";\n");
+                       appendPQExpBufferStr(q, ";\n");
 
                /*
                 * To create binary-compatible heap files, we have to ensure the same
@@ -12950,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"
@@ -12964,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");
                                }
                        }
 
@@ -12993,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];
@@ -13027,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",
@@ -13052,6 +13544,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                        }
                }
 
+               /*
+                * 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.
@@ -13159,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);
 
@@ -13168,7 +13699,8 @@ 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,
                                 NULL, 0,
                                 NULL, NULL);
@@ -13290,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;
@@ -13307,9 +13840,11 @@ 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(fout, q,
@@ -13327,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
@@ -13351,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);
@@ -13422,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. */
@@ -13627,7 +14173,7 @@ findLastBuiltinOid_V71(Archive *fout, const char *dbname)
        PQExpBuffer query = createPQExpBuffer();
 
        resetPQExpBuffer(query);
-       appendPQExpBuffer(query, "SELECT datlastsysoid from pg_database where datname = ");
+       appendPQExpBufferStr(query, "SELECT datlastsysoid from pg_database where datname = ");
        appendStringLiteralAH(query, dbname, fout);
 
        res = ExecuteSqlQueryForSingleRow(fout, query->data);
@@ -13779,18 +14325,18 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
        if (minv)
                appendPQExpBuffer(query, "    MINVALUE %s\n", minv);
        else
-               appendPQExpBuffer(query, "    NO MINVALUE\n");
+               appendPQExpBufferStr(query, "    NO MINVALUE\n");
 
        if (maxv)
                appendPQExpBuffer(query, "    MAXVALUE %s\n", maxv);
        else
-               appendPQExpBuffer(query, "    NO MAXVALUE\n");
+               appendPQExpBufferStr(query, "    NO MAXVALUE\n");
 
        appendPQExpBuffer(query,
                                          "    CACHE %s%s",
                                          cache, (cycled ? "\n    CYCLE" : ""));
 
-       appendPQExpBuffer(query, ";\n");
+       appendPQExpBufferStr(query, ";\n");
 
        appendPQExpBuffer(labelq, "SEQUENCE %s", fmtId(tbinfo->dobj.name));
 
@@ -13812,8 +14358,8 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 
        /*
         * 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
+        * 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
@@ -13898,7 +14444,7 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
        called = (strcmp(PQgetvalue(res, 0, 1), "t") == 0);
 
        resetPQExpBuffer(query);
-       appendPQExpBuffer(query, "SELECT pg_catalog.setval(");
+       appendPQExpBufferStr(query, "SELECT pg_catalog.setval(");
        appendStringLiteralAH(query, fmtId(tbinfo->dobj.name), fout);
        appendPQExpBuffer(query, ", %s, %s);\n",
                                          last, (called ? "true" : "false"));
@@ -13918,6 +14464,10 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
        destroyPQExpBuffer(query);
 }
 
+/*
+ * dumpTrigger
+ *       write the declaration of one user-defined table trigger
+ */
 static void
 dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 {
@@ -13930,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;
 
@@ -13955,23 +14509,23 @@ 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);
@@ -13981,31 +14535,31 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                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",
@@ -14024,18 +14578,18 @@ 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 (fout->remoteVersion >= 70300)
@@ -14064,12 +14618,12 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
                        }
 
                        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')
@@ -14080,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",
@@ -14120,18 +14674,26 @@ 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();
 
-       appendPQExpBuffer(query, "CREATE EVENT TRIGGER ");
+       appendPQExpBufferStr(query, "CREATE EVENT TRIGGER ");
        appendPQExpBufferStr(query, fmtId(evtinfo->dobj.name));
-       appendPQExpBuffer(query, " ON ");
+       appendPQExpBufferStr(query, " ON ");
        appendPQExpBufferStr(query, fmtId(evtinfo->evtevent));
        appendPQExpBufferStr(query, " ");
 
@@ -14142,9 +14704,9 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
                appendPQExpBufferStr(query, ") ");
        }
 
-       appendPQExpBuffer(query, "\n   EXECUTE PROCEDURE ");
+       appendPQExpBufferStr(query, "\n   EXECUTE PROCEDURE ");
        appendPQExpBufferStr(query, evtinfo->evtfname);
-       appendPQExpBuffer(query, "();\n");
+       appendPQExpBufferStr(query, "();\n");
 
        if (evtinfo->evtenabled != 'O')
        {
@@ -14153,19 +14715,19 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
                switch (evtinfo->evtenabled)
                {
                        case 'D':
-                               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, ";\n");
+               appendPQExpBufferStr(query, ";\n");
        }
        appendPQExpBuffer(labelq, "EVENT TRIGGER %s ",
                                          fmtId(evtinfo->dobj.name));
@@ -14344,12 +14906,12 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
        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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -14445,10 +15007,6 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                int                     nconfigitems;
                int                     nconditionitems;
 
-               /* Tables of not-to-be-dumped extensions shouldn't be dumped */
-               if (!curext->dobj.dump)
-                       continue;
-
                if (parsePGArray(extconfig, &extconfigarray, &nconfigitems) &&
                  parsePGArray(extcondition, &extconditionarray, &nconditionitems) &&
                        nconfigitems == nconditionitems)
@@ -14458,21 +15016,54 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[],
                        for (j = 0; j < nconfigitems; j++)
                        {
                                TableInfo  *configtbl;
+                               Oid                     configtbloid = atooid(extconfigarray[j]);
+                               bool            dumpobj = curext->dobj.dump;
 
-                               configtbl = findTableByOid(atooid(extconfigarray[j]));
+                               configtbl = findTableByOid(configtbloid);
                                if (configtbl == NULL)
                                        continue;
 
                                /*
-                                * Note: config tables are dumped without OIDs regardless of
-                                * the --oids setting.  This is because row filtering
-                                * conditions aren't compatible with dumping OIDs.
+                                * Tables of not-to-be-dumped extensions shouldn't be dumped
+                                * unless the table or its schema is explicitly included
                                 */
-                               makeTableDataInfo(configtbl, false);
-                               if (configtbl->dataObj != NULL)
+                               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)
                                {
-                                       if (strlen(extconditionarray[j]) > 0)
-                                               configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
+                                       /*
+                                        * Note: config tables are dumped without OIDs regardless
+                                        * of the --oids setting.  This is because row filtering
+                                        * conditions aren't compatible with dumping OIDs.
+                                        */
+                                       makeTableDataInfo(configtbl, false);
+                                       if (configtbl->dataObj != NULL)
+                                       {
+                                               if (strlen(extconditionarray[j]) > 0)
+                                                       configtbl->dataObj->filtercond = pg_strdup(extconditionarray[j]);
+                                       }
                                }
                        }
                }
@@ -14519,11 +15110,11 @@ getDependencies(Archive *fout)
         * 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 = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
 
@@ -14722,7 +15313,7 @@ addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
  * 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
+ * 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
@@ -14810,7 +15401,7 @@ findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
                        {
                                *allocDeps *= 2;
                                *dependencies = (DumpId *) pg_realloc(*dependencies,
-                                                                                         *allocDeps * sizeof(DumpId));
+                                                                                               *allocDeps * sizeof(DumpId));
                        }
                        (*dependencies)[*nDeps] = depid;
                        (*nDeps)++;
@@ -14818,9 +15409,9 @@ findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
                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.
+                        * 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);
 
@@ -14843,35 +15434,31 @@ findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
  *
  * 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(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 (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)
-               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");
 
        ExecuteSqlStatement(fout, query->data);
 
        destroyPQExpBuffer(query);
-       if (curSchemaName)
-               free(curSchemaName);
-       curSchemaName = pg_strdup(schemaName);
 }
 
 /*
@@ -14960,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;
@@ -14994,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);
@@ -15008,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(Archive *fout, 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 (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.
  *
@@ -15043,37 +15602,31 @@ fmtQualifiedId(Archive *fout, 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;
 }
 
 /*